关于教程:AI-电芯|可以快速上手的电池性能与表征预测工具合集

随着新能源汽车、便携电子设备和电化学储能零碎等行业的迅猛发展,电池电芯全生命周期内的性能监测、状态预计和寿命预测等问题越来越受到宽泛的关注,曾经成为制约这些行业进一步倒退的关键因素。 在试验侧,传统的开发模式依赖于大量电芯样品的长期测试评估,愈来愈跟不上不同场景的利用需要。一方面,电池样品生产制作过程中产线设施、物料与人力的高额投入,使得样品制作老本大幅回升。另一方面,电池下仓后对电热平安等性能测试评估的周期十分长,例如电池循环寿命、存储寿命等测试往往会继续三个月甚至更长时间,导致测试资源始终处于十分紧缺的状态。 为应答电芯开发效率慢、周期长、老本高的挑战,基于物理模型的电芯仿真工具在工业界一直利用,对“虚构电芯”进行“虚构测试”成为降本增效的无效伎俩。 Source: Southwest Research Insititute 官网 (www.swri.org)然而,电芯仿真始终面临难以兼顾模型的准确性和对计算资源宏大的需要。一方面,仿真模型往往在形容物理过程和建模时做了简化,和实在电池体系的物理过程存在差别。模型中要害参数的难以获取,则进一步导致仿真模型的准确性无奈失去保障;另一方面,一旦引入更简单的建模和反馈机理后,模型的计算量和稳定性往往成为了限度模型利用的瓶颈。此外,新型电池资料的引入和电池设计、构造的扭转,都可能会导致模型对应参数的失准,这限度了模型的拓展性。 Source: Active Cell Balancing for Life Cycle Extension of Lithium-Ion Batteries under Thermal Gradient (DOI:10.1109/ISLPED52811.2021.9502500) 此时,AI的呈现给了咱们新的心愿。AI与电芯的联合无望带来了革命性的扭转,这不仅无望解决仿真层面模型驱动自带的精度和算力需要难以兼顾的问题,也能更好地利用了试验数据的后果。应用带标签数据的监督机器学习领有良好的预测准确性。深度学习办法可能在大规模数据集上主动学习到高层次和形象的特色示意,具备较高的预测和分类准确率。以长短期记忆模型(LSTM)为例,在长时间序列解决上的优异体现使得它非常适合用来解决电芯的工夫相干数据,如充放电过程。 而企业积攒的海量电芯数据更是提供了大规模预训练模型的可能。在预训练的过程中,模型能够学习到丰盛的畛域常识和语义信息。在预训练模型的根底上,咱们能够应用大量有标签数据进行微调,以实现在特定工作上的高效学习。这种办法在自然语言解决、计算机视觉等畛域曾经获得了显著的胜利。从久远来看,大规模预训练模型将为电池电芯畛域带来微小的后劲和倒退空间。 AI+电芯 Notebook本期 Notebook,咱们给大家带来的一个 AI+电芯利用案例合集。它不仅蕴含了 SOC(电池荷电状态)预计和寿命预测这样的热门利用,也蕴含了电池表征方面,如 EIS 阻抗谱和 ECM 等效电路模型的预测。对于关注AI+电芯的你来说,这是一个不容错过的上手好机会。 值得一提的是,这次合集中的案例大多并非是当下最好的模型后果(SOTA)。真正重要的并不是所谓的SOTA,而是适宜于场景的、真正有用的模型。这须要咱们更好地协同起来,突破壁垒、凝聚共识、发明连贯、造成迭代,独特建设 AI for Battery 更好的将来。 点击下方图片,拜访本期 Notebook: 欢送来 Notebook 案例广场,获取更多有意思的notebook实际~感兴趣的同学也能够浏览原文查看。

September 5, 2023 · 1 min · jiezi

关于教程:手把手推导分布式矩阵乘的最优并行策略

作者|郭冉、李一鹏、柳俊丞、袁进辉 罕用深度学习框架的主动并行机制还不够欠缺,还须要用户依据教训来配置并行形式,这给开发者带来了不小的智力累赘。因而,实现主动最优并行就成为一个乏味的课题。 矩阵乘是深度学习最罕用的底层计算原语,譬如卷积算子,注意力机制都是通过矩阵乘来实现的,所以大规模神经网络的并行实现大多数时候也是在解决分布式矩阵乘。本文就以如何最优地实现分布式矩阵乘为例来展现主动并行的解决思路。 1 如何实现最优的分布式矩阵乘?通过上一篇文章《手把手推导 Ring all-reduce 的数学性质》咱们晓得了常见集群通信操作的通信量和所需通信工夫的数学性质,在这篇文章里咱们看看怎么应用这些性质来抉择最优的并行矩阵乘策略。 在文章《如何超过数据并行和模型并行:从GShard 谈起》,咱们介绍了如何从个别的数据并行、模型并行提炼出最一般性的算子并行的形象示意 SBP。 假如咱们心愿在4张显卡(2台服务器,每台服务器上有2张显卡)上实现一个矩阵乘\( X\times W=Y \),也就是\(y_{ij}=\sum_{k}{x_{ik}\times w_{kj}}\),其中\( X \)和\( W \)依照特定的 SBP 签名被摆放(place)到4张显卡上,那么将有多个形式实现分布式矩阵乘,它们在数学上等价,不过须要调用的集群通信操作不同,从而触发的通信代价也不同。 沿用《手把手推导 Ring all-reduce 的数学性质》里的符号,\( p \)示意设施数,\( V \)示意矩阵大小 \( V_{x} \)示意矩阵\( X \)的大小,\( V_{w} \)示意矩阵\( W \)的大小), \( \beta \)示意传输带宽。 2 数据并行还是模型并行?图 1:基于1D 矩阵乘的数据并行 如果\( X \)和\( W \)的SBP签名别离是\( S(0) \)和 \( B \) ,那么能够推导进去\( Y \)的 SBP是\( S(0) \),也就是左矩阵\( X \)是行划分,右矩阵\( W \)是在各个卡上是截然不同的拷贝(broadcast)。如果\( X \)示意特色数据 (feature map), \( W \)示意模型参数,那么这是一个典型的数据并行,上面咱们剖析一下数据并行的通信代价。 ...

June 1, 2022 · 3 min · jiezi

关于教程:录制视频教程的工作流浅析

零、前言本周的工作,除了敲代码以外,次要是把团队的教程学习一遍,而后对于不欠缺的局部打上补丁。 因为在”解决文件大小“的问题上破费了很多精力,解决视频的总体效率很低。因而本文旨在将这一套解决流程固定下来,以便晋升后续的效率。 总体的流程大抵包含: 屏幕录制剪辑渲染压抑公布 一、屏幕录制市面上最支流的录屏软件有两个: BandiCam 和 OBS。 BandiCam益处很多,但最大的问题是付费,尽管能够破解,但每次版本更新都要花工夫去寻找破解,所以不举荐。 OBS是开源软件,间接就能够收费应用,而且Mac、Linux、Windows全平台兼容,所以咱们应用OBS。 装置好之后能够跳过向导,间接来到设置页面: 录像品质抉择:高质量,中等比特流。低了影响画质,高了文件太大。录像格局:mkv。编码器:如果有反对硬件编码就选硬件,否则抉择软件。 为什么应用mkv而不是MP4格局? mkv不是间接用来播放的视频格式,而是一种半成品格局,具备文件小的特点,同时能够保留更多的原始数据,多条视频、音频轨道独自存储(比如说,一个录屏文件同时录制了麦克风和零碎音频,前期能够独自调节某一个音轨的音量大小,而MP4只能调节整体的音量)。最厉害的是,即便文件的后一部分损坏,前一部分也能够失常播放,也就是说,不怕录像时断电导致文件全副损坏的危险。而MP4是真真正正的视频格式,不具备以上个性。 用一个不失当的比喻:Java是编译成两头码而后用Java虚拟机来运行,而C语言是彻底编译成机器码间接用二进制来运行。 非要说mkv的毛病,那就是必须转换成mp4能力实现全平台播放。 接下来设置分辨率: 根底分辨率是软件中实践上生成的像素数量输入分辨率是导出视频文件时,文件的理论分辨率如果根底分辨率大于输入分辨率,就能够录制1080P的屏幕并输入720P的视频文件来减小体积为了不便,对于16:9的显示器,这两处倡议全写1080P 增加显示器采集,并让画面正好充斥画布: 全副录制实现后,应用OBS自带的”录制转封装“就能一键批量转换成mp4格局了,用于交付审核以及剪辑: 剪辑最罕用到的性能: 抉择工具,选取视频、插入视频剃刀工具,把素材分段文字工具,增加阐明文字转场工具,视频之间过渡这种根底的不能再根底的性能,所有的剪辑软件都有但依然倡议Windows应用PremierePro,因为教程多,好学Mac如果应用FinalCutPro上手会更简略,而且苹果自家软件有神秘加成 渲染对于剪辑软件来说,即便导出设置和原始文件截然不同,导出的文件还是比录屏的原始文件大的多。所以咱们必须再通过一轮压抑,能力管制文件体积。对于渲染这一步来说,能够设置的略微大一些,只有不损失画质即可。 对于录屏来说,应用H.264编码、1920*1080、30fps、1500kbps就能够实现不损失画质 Premiere有一个渲染器叫Media Encoder(ME),用来批处理渲染视频。当Pr的视频制作实现后,就提交到ME的队列中,并且设定对立的输入格局,ME会依照先后顺序在后盾应用预设好的格局来渲染,此时Pr依然能够去做别的事件。这样就实现了批处理,不必每次都繁琐的设置一大堆输入参数了。 对于苹果的FinalCut,同样有渲染器Compressor,有殊途同归之妙。 压抑这一步的目标是减小文件体积,举荐的是开源软件HandBrake,反对一键压抑,自带多种预设,并且反对队列。 间接应用超快1080P 30即可,导出的文件很小,清晰度简直没有损失。 公布当初咱们曾经有了文件体积小并且不损失画质的最终文件,导出后就能够公布到各种平台了。 此外,如果有制作视频目录或者校核的需要,把工夫很长的教程从新看一遍显然是效率比拟低的,这里举荐一个chrome插件,自在调整倍速,最高16倍速,插件名为Global Speed: 如果视频是本地文件,应用VLC,能够实现最高四倍速播放: 版权申明本文作者:河北工业大学梦云智开发团队 - 刘宇轩新人经验不足,有倡议欢送交换,有谬误欢送轻喷

January 17, 2022 · 1 min · jiezi

关于教程:flashfxp教程详解flashfxp教程介绍

FlashFXP是一个功能强大的 FXP/FTP 软件,交融了一些其余优良 FTP软件的长处,如像 CuteFTP 一样能够比拟文件夹,反对黑白文字显示;像 BpFTP 反对多文件夹抉择文件,可能缓存文件夹;像 LeapFTP 一样的外观界面,甚至设计思路也差相好像。反对上传、下载及第三方文件续传;能够跳过指定的文件类型,只传送 须要的文件;能够自定义不同文件类型的显示色彩;能够缓存远端文件夹列表,反对FTP代理及 Socks 3&4;具备防止闲暇性能,避免被站点踢出。 IIS7服务器管理工具,是一款十分好的管理工具了。外面的性能除了批量治理,还有很多别的性能,次要也是性能也比拟全面,置信大多数应用的网站工作人员都比拟相熟了。它外面还可能定时上传下载、定时备份和自动更新。把你花在更新上的工夫都省了。 除了在ftp下面有这么多的性能以外,它别的性能也都是比拟实用的。实用在Windows和liunx操作系统。还反对Vnc和Ftp批量操作。同时它还具备同步操作、到期揭示、数据安全和定期执行的性能。第一步:登录iis7服务器管理工具 第二步:抉择上传下载 第三步:抉择FTP 第四步:点击设置,在设置页面抉择定时工作的日期和工夫等,选好当前间接敞开小窗口,无需保留 第五步:在ftp列表前勾选须要关上的ftp 第六步:点击关上,连贯当前即可进行ftp文件传输

September 30, 2020 · 1 min · jiezi

关于教程:架设ftp服务器怎么架设ftp服务器教程

想要架设ftp服务器,其实很简略,只须要下载一个ftp服务器,自己以前也不晓得该怎么弄,然而起初发现了一款很容易上手ftp服务器,特地适宜老手应用,上面来就给大家介绍一下吧。 这款ftp客户端就是IIS7服务器管理工具,其最次要的特点是:定时上传,定时下载,主动备份和更新。 此外,它还能批量治理win系列的操作系统, linux操作系统以及linux的vnc、win的vnc,有主动重连,主动重传,自定义传输模式,线程,编码,删除到回收站,大量文件疾速加载,边加载边传输,批量连贯一键敞开等性能,绿色的界面看上去也是十分清爽爽朗,长时间应用下来眼睛也不会太疲劳。应用工具:IIS7服务器管理工具第一步:登录iis7服务器管理工具 第二步:抉择上传下载 第三步:抉择FTP 第四步:点击设置,在设置页面抉择定时工作的日期和工夫等,选好当前间接敞开小窗口,无需保留 第五步:在ftp列表前勾选须要关上的ftp 第六步:点击关上,连贯当前即可进行ftp文件传输

September 29, 2020 · 1 min · jiezi

IDEA-201923破解激活教程激活到2089年8月亲测有效

本来笔者这边是有个正版激活码可以使用的,但是,2019.9月3号的时候,一些小伙伴反映这个注册码已经失效了,于是拿着自己的 IDEA, 赶快测试了一下,果不其然,已然是不能用了。 好在,笔者又找到了新的激活方法。按照此教程,能成功激活到 2089 年 8 月,无图无真相: 在激活之前,主要注意:无需改动 host 文件。 步骤如下: 开始激活1.打开已经安装好的 IDEA, 我们选择 30 天免费试用,先进去再说: 成功进入 IDEA 以后,我们随便创建一个项目/或者打开个旧的项目,点击顶部的 Help 菜单 -> Edit Custom VM Options: 添加破解补丁位置打开后,我们在最后一行添加如下配置: -javaagent:D:\jetbrains-agent.jar注意:D:\jetbrains-agent.jar 是我存放破解补丁的位置,你可以自定义成自己存放的位置,注意目录中不要带有中文。注意:因某些限制,最新激活码、破解补丁已放置在笔者公众号上,请关注微信公众号: 小哈学Java, 回复关键字:idea, 即可免费无套路免费激活码、破解补丁,持续更新中~。 打开激活框,移除之前的 License (非常重要)若你的 IDEA 已经使用了老的 License, 注意移除,否则会导致激活不成功。 如没有 Remove License 按钮,则不需要关心,直接看下一步。 重启 IDEA引入破解补丁以后,重启 IDEA。 填入激活码将公众号回复的激活码,填入进去: 注意:因某些限制,最新激活码、破解补丁已放置在笔者公众号上,请关注微信公众号: 小哈学Java, 回复关键字:idea, 即可免费无套路免费激活码、破解补丁,持续更新中~。添加的时候,要注意前后是否带有空格,有则需要去掉,点击 OK 按钮。 再次查看 IDEA 的过期时间,你就可以看到已经激活到 2089 年辣~ 祝您学习愉快~ ...

October 1, 2019 · 1 min · jiezi

Schema-Registry-教程

物联网设备终端种类繁杂,各厂商使用的编码格式各异,所以在接入物联网平台的时候就产生了统一数据格式的需求,以便平台之上的应用进行设备管理。 EMQ X 企业版 3.4.0 提供了 Schema Registry 功能,提供编解码能力。Schema Registry 管理编解码使用的 Schema、处理编码或解码请求并返回结果。Schema Registry 配合规则引擎,可适配各种场景的设备接入和规则设计。 数据格式下图展示了 Schema Registry 的一个应用案例。多个设备上报不同格式的数据,经过 Schema Registry 解码之后,变为统一的内部格式,然后转发给后台应用。 [图1: 使用 Schema Registry 对设备数据进行编解码] 二进制格式支持EMQ X 3.4.0 内置的 Schema Registry 数据格式包括 Avro 和 Protobuf。Avro 和 Protobuf 是依赖 Schema 的数据格式,编码后的数据为二进制,使用 Schema Registry 解码后的内部数据格式(Map,稍后讲解) 可直接被规则引擎和其他插件使用。此外 Schema Registry 支持用户自定义的 (3rd-party) 编解码服务,通过 HTTP 或 TCP 回调的方式,进行更加贴近业务需求的编解码。 架构设计Schema Registry 为 Avro 和 Protobuf 等内置编码格式维护 Schema 文本,但对于自定义编解码 (3rd-party) 格式,如需要 Schema,Schema 文本需由编解码服务自己维护。Schema Registry 为每个 Schema 创建一个 Schema ID,Schema API 提供了通过 Schema ID 的添加、查询和删除操作。 ...

September 19, 2019 · 5 min · jiezi

译670免费在线编程和计算机科学课程

670+免费在线编程和计算机科学课程 七年前,麻省理工学院和斯坦福大学等大学首次向公众开放免费在线课程。如今,全球已有近1000所学校创建了数千个免费在线课程,俗称Massive Open Online Courses或MOOC。 我已经编制了670多个这样的免费在线课程列表,你可以在今年夏天开始。为此,我利用了Class Central的12,000多个在线课程数据库。我还列出了每门课程的平均评分。 我根据他们的难度级别将这些课程分为以下几类: 初学者中间高级首次提供的课程标记为[新]。 其中许多课程完全是自定进度的。其余的将在不同的时间开始。您可以在2019年晚些时候在Class Central的计算机科学,数据科学和编程主题页面上找到完整的技术相关课程列表。 我知道这个很长的列表,对于刚接触编程的学习者来说可能是令人生畏的。在这种情况下,您可能会发现David Venturi对最佳数据科学在线课程的建议很有用 - 即使您不想学习数据科学。我希望将来能够创建更多这些指南。 最后,如果您无法确定如何免费注册Coursera课程,请不要担心 - 我也写了一篇关于如何做到这一点的文章。 Beginner (158)An Introduction to Interactive Programming in Python (Part 1) from Rice University ★★★★★(2909)Introduction to Computer Science and Programming Using Python from Massachusetts Institute of Technology ★★★★★(99)Learn to Program: The Fundamentals from University of Toronto ★★★★★(86)Intro to Computer Science from University of Virginia ★★★★☆(61)CS50's Introduction to Computer Science from Harvard University★★★★★(53)Ruby on Rails: An Introduction from Johns Hopkins University ★★★☆☆(50)Introduction to HTML5 from University of Michigan ★★★★☆(37)Internet History, Technology, and Security from University of Michigan★★★★★(35)Introduction to Linux from Linux Foundation ★★★★☆(34)How to Use Git and GitHub[New] Introduction to Internationalization and Localization from University of Washington[New] Principles of Secure Coding from University of California, Davis[New] Identifying Security Vulnerabilities from University of California, Davis[New] Introduction to R Software from Indian Institute of Technology Kanpur[New] Diagramas UML estructurales para la Ingeniería del Software from Universitat Politècnica de València[New] Object oriented analysis and design from Indian Institute of Technology, Kharagpur[New] AWS Fundamentals: Addressing Security Risk from Amazon Web Services[New] プログラミングしながら学ぶコンピュータサイエンス入門 : Introduction to Computer Science and Programming from Tokyo Institute of Technology[New] Database and Content Organisation from IGNOU[New] Computer Networks from Devi Ahilya Viswavidyalaya, Indore[New] Computer Fundamentals from Devi Ahilya Viswavidyalaya, IndoreIntro to HTML and CSSIntroduction to VBA/Excel Programming from Cal Poly Pomona ★★★★☆(21)Build a Modern Computer from First Principles: From Nand to Tetris (Project-Centered Course) from Hebrew University of Jerusalem ★★★★★(14)Programming Basics from Indian Institute of Technology Bombay ★★☆☆☆(13)Computer Science 101 from Stanford University ★★★★☆(11)Introduction to CSS3 from University of Michigan ★★★★★(11)Creative Programming for Digital Media & Mobile Apps from University of London International Programmes ★★★★☆(10)HTML5 Coding Essentials and Best Practices from World Wide Web Consortium (W3C) ★★★★☆(9)Introduction to Computer Networking from Stanford University ★★★★★(8)Introduction to the Internet of Things and Embedded Systems from University of California, Irvine ★★★★☆(8)Usable Security from University of Maryland, College Park ★★★☆☆(8)Introduction to Bootstrap - A Tutorial from Microsoft ★★★☆☆(8)Code Yourself! An Introduction to Programming from University of Edinburgh★★★★☆(7)HTML, CSS, and Javascript for Web Developers from Johns Hopkins University★★★★★(6)Learn to Program: Crafting Quality Code from University of Toronto ★★★★★(6)Intro to Relational DatabasesParadigms of Computer Programming – Abstraction and Concurrency from Université catholique de Louvain ★★★★☆(4)Paradigms of Computer Programming – Fundamentals from Université catholique de Louvain ★★★★★(4)Introduction to jQuery from Microsoft ★★★★☆(4)Programming in Scratch from Harvey Mudd College ★★★★★(4)How To Create a Website in a Weekend! (Project-Centered Course) from State University of New York ★★★★★(3)Introduction to Programming for the Visual Arts with p5.js from University of California, Los Angeles ★★★★☆(3)HTML5 and CSS Fundamentals from World Wide Web Consortium (W3C)★★★★☆(3)Linux Command Line BasicsThe Beauty and Joy of Computing - AP® CS Principles Part 1 from University of California, Berkeley ★★★★★(2)Object-Oriented Programming from Indian Institute of Technology Bombay★★★★☆(2)The Computing Technology Inside Your Smartphone from Cornell University★★★★★(2)Introduction to HTML and JavaScript from Microsoft ★★★★★(2)Think. Create. Code from University of Adelaide ★★★★★(2)CS For All: Introduction to Computer Science and Python Programming from Harvey Mudd College ★★★★★(2)Networks: Friends, Money, and Bytes from Princeton University ★★★☆☆(1)Programando con Java para aplicaciones Android from Universidad Nacional Autónoma de México ★★★★★(1)Android Basics: Make Your First App from Google ★★★★★(1)Computing: Art, Magic, Science from ETH Zurich ★★★★☆(1)MyCS: Computer Science for Beginners from Harvey Mudd College ★★★☆☆(1)CS50's Web Programming with Python and JavaScript from Harvard UniversityCS50's Understanding Technology from Harvard UniversityCS50's Computer Science for Business Professionals from Harvard UniversityCS50's Mobile App Development with React Native from Harvard UniversityCS50's Introduction to Game Development from Harvard UniversityPrinciples of Computing from Stanford UniversityHacker Tools from Massachusetts Institute of TechnologyThe Beauty and Joy of Computing - AP® CS Principles Part 2 from University of California, BerkeleyComputational Thinking for Problem Solving from University of PennsylvaniaThe Unix Workbench from Johns Hopkins UniversityProgramming Fundamentals from Duke UniversityInteracting with the System and Managing Memory from Duke UniversityComputer Science: Programming with a Purpose from Princeton UniversityIntroduction to Cybersecurity from University of WashingtonPython Programming Essentials from Rice UniversityIntroduction to Computer Programming from University of London International ProgrammesHow Computers Work from University of London International ProgrammesSoftware Engineering: Introduction from The University of British ColumbiaIntroduction to Web Development from University of California, Davis from St. Petersburg State Polytechnic UniversityWeb Design: Strategy and Information Architecture from California Institute of the ArtsWeb Development and Design using Wordpress from California Institute of the ArtsCyber Security Economics from Delft University of TechnologyScratch: Programmeren voor kinderen (8+) from Delft University of TechnologyExcel/VBA for Creative Problem Solving, Part 2 from University of Colorado Boulder from Moscow Institute of Physics and Technology from Moscow Institute of Physics and TechnologyWeb Coding Fundamentals: HTML, CSS and Javascript from National University of SingaporeMonetize your Android Applications from Galileo UniversityAndroid App Development for Beginners from Galileo UniversityJava Fundamentals for Android Development from Galileo UniversityAP Computer Science A: Java Programming Polymorphism and Advanced Data Structures from Purdue UniversityAP Computer Science A: Java Programming Loops and Data Structures from Purdue UniversityAP Computer Science A: Java Programming Classes and Objects from Purdue UniversityIntroduction to TCP/IP from Yonsei UniversityDeep Learning for Business from Yonsei UniversityCyber Security Basics: A Hands-on Approach from Universidad Carlos iii de MadridProblem Solving, Programming, and Video Games from University of AlbertaIntroduzione a LaTeX from University of Modena and Reggio EmiliaBlockchain 360: A State of the Art for Professionals from EIT DigitalWeb Accessibility from GoogleMobile Web Development from GoogleTechnical Support Fundamentals from GoogleIntroduction to Design Thinking from MicrosoftCSS Basics from MicrosoftLearn to Program in Java from MicrosoftIntroduction to NodeJS from MicrosoftWriting Professional Code from MicrosoftObject Oriented Programming in Java from MicrosoftLogic and Computational Thinking from MicrosoftIntroduction to ReactJS from MicrosoftHow Entrepreneurs in Emerging Markets can master the Blockchain Technology from University of Cape TownC Programming: Modular Programming and Memory Management from DartmouthC Programming: Using Linux Tools and Libraries from DartmouthLinux Basics: The Command Line Interface from DartmouthC Programming: Advanced Data Types from DartmouthC Programming: Language Foundations from Institut Mines-TélécomC Programming: Getting Started from DartmouthC Programming: Pointers and Memory Management from DartmouthSoftware Design as an Element of the Software Development Lifecycle from University of Colorado SystemSoftware Design as an Abstraction from University of Colorado SystemSoftware Design Methods and Tools from University of Colorado SystemProactive Computer Security from University of Colorado SystemIntroduction to Cybersecurity for Business from University of Colorado SystemComputing: Art, Magic, Science - Part II from ETH ZurichTCP/IP and Advanced Topics from University of Colorado SystemIntroduction to Open Source Networking Technologies from Linux FoundationBlockchain: Understanding Its Uses and Implications from Linux FoundationIntroducción a la programación en C: Instrucciones de control y ficheros de texto from Universidad Autónoma de MadridMobile Computing with App Inventor – CS Principles from The University of WarwickIntroduction to the Internet of Things (IoT) from Curtin UniversitySoftware Engineering Essentials from Technische Universität München (Technical University of Munich)Cyber Attack Countermeasures from New York University (NYU)Web Security Fundamentals from KU Leuven UniversityIntroduction to Cyber Attacks from New York University (NYU) (Databases) from Saint Petersburg State UniversityArduino Programming, from novice to ninja from Institut Mines-TélécomVideo Game Design and Balance from Rochester Institute of TechnologyIntroducción a la programación en Python I: Aprendiendo a programar con Python from Pontificia Universidad Católica de ChileIntrodução à Ciência da Computação com Python Parte 1 from Universidade de São PauloIntrodução à Ciência da Computação com Python Parte 2 from Universidade de São PauloProgramación Orientada a Objetos from MéxicoXComputing Form and Shape: Python Programming with the Rhinoscript Libraryfrom Rhode Island School of DesignIntroduction to MongoDB from MongoDB UniversityProgramación Orientada a Objetos con Python from Universidad AustralDiseñando páginas web con Bootstrap 4 from Universidad AustralWeb Applications for EverybodyIntroduction to Virtual RealitySwift for BeginnersVersion Control with Git from AtlassianElements of AI from University of HelsinkiAndroid for BeginnersHTTP & Web ServersNetwork Protocols and Architecture from CiscoGitHub & CollaborationES6 - JavaScript ImprovedLearn Swift Programming SyntaxHome Networking Basics from CiscoData Communications and Network Services from CiscoInternet Connection: How to Get Online? from CiscoIntroduction to Cisco Networking from CiscoVersion Control with GitIntermediate (377)Machine Learning from Stanford University ★★★★★(261)Divide and Conquer, Sorting and Searching, and Randomized Algorithms from Stanford University ★★★★★(60)Functional Programming Principles in Scala from École Polytechnique Fédérale de Lausanne ★★★★★(58)Algorithms, Part I from Princeton University ★★★★☆(49)Cryptography I from Stanford University ★★★★★(45)Programming Mobile Applications for Android Handheld Systems: Part 1 from University of Maryland, College Park ★★★★☆(38)CS188.1x: Artificial Intelligence from University of California, Berkeley★★★★★(30)Principles of Computing (Part 1) from Rice University ★★★★★(26)[New] Human-Computer Interaction I: Fundamentals & Design Principles from Georgia Institute of Technology[New] Human-Computer Interaction II: Cognition, Context & Culture from Georgia Institute of Technology[New] Human-Computer Interaction III: Ethics, Needfinding & Prototypingfrom Georgia Institute of Technology[New] Human-Computer Interaction IV: Evaluation, Agile Methods & Beyondfrom Georgia Institute of Technology[New] Practical Machine Learning with Tensorflow from Google[New] Identifying Security Vulnerabilities in C/C++Programming from University of California, Davis[New] Introduction to parallel Programming in Open MP from Indian Institute of Technology Delhi[New] Open Infrastructure to Support the 5G Transition from Linux Foundation[New] Business Considerations for Modernizing Networks for 5G, IoT and AIfrom Linux Foundation[New] Inclusion and Technology Design from Indian Institute of Technology BangalorePractical Machine Learning from Johns Hopkins University ★★★☆☆(22)Software Security from University of Maryland, College Park ★★★★★(22)Algorithms, Part II from Princeton University ★★★★★(21)Responsive Website Basics: Code with HTML, CSS, and JavaScript from University of London International Programmes ★★★★☆(21)Agile Development Using Ruby on Rails - The Basics from University of California, Berkeley ★★★★★(19)Cloud Computing Concepts, Part 1 from University of Illinois at Urbana-Champaign ★★★☆☆(19)Automata Theory from Stanford University ★★★★☆(17)C++ For C Programmers, Part A from University of California, Santa Cruz★★★☆☆(16)Principles of Computing (Part 2) from Rice University ★★★★☆(15)Programming Mobile Applications for Android Handheld Systems: Part 2 from University of Maryland, College Park ★★★★☆(15)The Nature of Code from Processing Foundation ★★★★★(15)Algorithmic Thinking (Part 1) from Rice University ★★★★☆(14)Design of Computer Programs from Stanford University ★★★★☆(13)Intro to Machine Learning from Stanford University ★★★★☆(12)Algorithmic Toolbox from University of California, San Diego ★★★★☆(12)Discrete Optimization from University of Melbourne ★★★★☆(12)Responsive Web Design from University of London International Programmes★★★☆☆(11)Introduction to Game Development from Michigan State University★★★★☆(11)Introduction to Functional Programming from Delft University of Technology★★★★☆(11)Interactivity with JavaScript from University of Michigan ★★★★☆(10)Introduction to Software Product Management from University of Alberta★★★★☆(10)Android Development for Beginners from Google ★★★★☆(10)The Arduino Platform and C Programming from University of California, Irvine★★★☆☆(9)Algorithmic Thinking (Part 2) from Rice University ★★★★☆(9)Programming Languages from University of Virginia ★★★☆☆(9)Software Processes and Agile Practices from University of Alberta ★★★★☆(9)Image and Video Processing: From Mars to Hollywood with a Stop at the Hospital from Duke University ★★★★☆(8)Text Retrieval and Search Engines from University of Illinois at Urbana-Champaign ★★★☆☆(8)Cryptography from University of Maryland, College Park ★★★★☆(8)Advanced Styling with Responsive Design from University of Michigan★★★★☆(7)Cloud Computing Applications, Part 1: Cloud Systems and Infrastructure from University of Illinois at Urbana-Champaign ★★★☆☆(7)Software Testing from University of Utah ★★★★☆(7)Internet of Things: How did we get here? from University of California, San Diego★★☆☆☆(6)Introduction To Swift Programming from University of Toronto ★☆☆☆☆(6)Learning from Data (Introductory Machine Learning course) from California Institute of Technology ★★★★☆(6)Client Needs and Software Requirements from University of Alberta★★★★☆(6)Responsive Web Design Fundamentals from Google ★★★★☆(6)Intro to AJAXAgile Development Using Ruby on Rails - Advanced from University of California, Berkeley ★★★★★(5)Ruby on Rails Web Services and Integration with MongoDB from Johns Hopkins University ★★★★★(5)Cloud Computing Concepts: Part 2 from University of Illinois at Urbana-Champaign ★★★★★(5)Data Structures and Performance from University of California, San Diego★★★★★(5)Computer Graphics from University of California, San Diego ★★★★☆(5)Introduction to Meteor.js Development from University of London International Programmes ★★★★★(5)Web Application Development with JavaScript and MongoDB from University of London International Programmes ★★★★☆(5)How to Code: Simple Data from The University of British Columbia ★★★★☆(5)Developing Android Apps from Google ★★★★☆(5)Julia Scientific Programming from University of Cape Town ★★★★★(5)Data Wrangling with MongoDB from MongoDB University ★★★★☆(5)Intro to DevOps from Nutanix ★★★☆☆(5)Intro to iOS App Development with SwiftParallel Programming ConceptsInterfacing with the Arduino from University of California, Irvine ★★★★☆(4)Algorithms on Strings from University of California, San Diego ★★★☆☆(4)Computer Architecture from Princeton University ★★★★★(4)Analysis of Algorithms from Princeton University ★★★★★(4)Computer Networking from Georgia Institute of Technology ★★★★☆(4)Software Development Process from Georgia Institute of Technology★★★☆☆(4)Cloud Networking from University of Illinois at Urbana-Champaign ★★★★☆(4)HTML5 Game Development from Google ★★★☆☆(4)Website Performance Optimization from Google ★★★★☆(4)Practical Numerical Methods with Python from George Washington University★★★★☆(4)Database Management Essentials from University of Colorado System★★★★☆(4)Interactive Computer Graphics from The University of Tokyo ★★☆☆☆(4)Software Debugging from Saarland University ★★★★★(4)Software Construction in Java from Massachusetts Institute of Technology★★★★★(3)The Raspberry Pi Platform and Python Programming for the Raspberry Pi from University of California, Irvine ★★★★☆(3)Foundations of Objective-C App Development from University of California, Irvine ★★★☆☆(3)Data Structures from University of California, San Diego ★★★☆☆(3)Networks Illustrated: Principles without Calculus from Princeton University★★★★☆(3)VLSI CAD Part I: Logic from University of Illinois at Urbana-Champaign★★★★★(3)Internet of Things: Setting Up Your DragonBoard™ Development Platformfrom University of California, San Diego ★★★☆☆(3)Mastering the Software Engineering Interview from University of California, San Diego ★★★★☆(3)DevOps for Developers: How to Get Started from Microsoft ★★★★☆(3)Querying Data with Transact-SQL from Microsoft ★★★★☆(3)Autonomous Mobile Robots from ETH Zurich ★★★☆☆(3)Intro to AlgorithmsCompilers from Stanford University ★★★★☆(2)Mobile Application Experiences Part 1: From a Domain to an App Idea from Massachusetts Institute of Technology ★★★★★(2)Rails with Active Record and Action Pack from Johns Hopkins University★★★★☆(2)Algorithms on Graphs from University of California, San Diego ★★★★☆(2)Advanced Data Structures in Java from University of California, San Diego★★★★☆(2)Internet of Things: Communication Technologies from University of California, San Diego ★★★☆☆(2)App Design and Development for iOS from University of Toronto ★★★☆☆(2)iOS App Development Basics from University of Toronto ★★★★☆(2)Game Development for Modern Platforms from Michigan State University★★★★★(2)Introduction to Mobile Application Development using Android from The Hong Kong University of Science and Technology ★★★★☆(2)Agile Planning for Software Products from University of Alberta ★★★☆☆(2)Browser Rendering Optimization from Google ★★★★☆(2)UX Design for Mobile Developers from Google ★★★★★(2)Developing International Software, Part 1 from Microsoft ★★★★☆(2)Analyzing and Visualizing Data with Power BI from Microsoft ★★★★★(2)Agile Software Development from ETH Zurich ★★★★★(2)Build Your First Android App (Project-Centered Course) from École Centrale Paris ★★★☆☆(2)Approximation Algorithms Part I from École normale supérieure ★★★★★(2)JavaScript TestingFull Stack FoundationsConfiguring Linux Web ServersSingle Page Web Applications with AngularJS from Johns Hopkins University★★★★★(1)Best Practices for iOS User Interface Design from University of California, Irvine★★★★★(1)Interfacing with the Raspberry Pi from University of California, Irvine★☆☆☆☆(1)Machine Learning: Unsupervised Learning from Brown University ★★★★☆(1)Advanced Algorithms and Complexity from University of California, San Diego★★★☆☆(1)Software Architecture & Design from Georgia Institute of Technology★★★★★(1)Responsive Website Tutorial and Examples from University of London International Programmes ★★★★★(1)Managing an Agile Team from University of Virginia ★★☆☆☆(1)MATLAB and Octave for Beginners from École Polytechnique Fédérale de Lausanne ★☆☆☆☆(1)Web Application Development: Basic Concepts from University of New Mexico★★★★☆(1)Android: Introducción a la Programación from Universitat Politècnica de València★★★★☆(1)Algorithms from Indian Institute of Technology Bombay ★★★★★(1)Developing Scalable Apps in Python from Google ★★★★☆(1)Android Basics: Multiscreen Apps from Google ★★★★☆(1)Gradle for Android and Java from Google ★★★★★(1)Developing Scalable Apps in Java from Google ★★★★☆(1)Google Cloud Platform Fundamentals: Core Infrastructure from Google★★★★☆(1)JavaScript Promises from Google ★★★★★(1)Principles of Machine Learning from Microsoft ★★★★★(1)用Python玩转数据 Data Processing Using Python from Nanjing University★★★★★(1)Cybersecurity and Mobility from University System of Georgia ★☆☆☆☆(1)Design and Analysis of Algorithms from Chennai Mathematical Institute★★★☆☆(1)Technical Interview from Pramp ★★★★★(1)HTML5 Apps and Games from World Wide Web Consortium (W3C) ★★★☆☆(1)Intro to Theoretical Computer ScienceNetworking for Web DevelopersUsing Python for Research from Harvard UniversityAlgorithms: Design and Analysis from Stanford UniversityGreedy Algorithms, Minimum Spanning Trees, and Dynamic Programming from Stanford UniversityProbabilistic Graphical Models 3: Learning from Stanford UniversityAlgorithms: Design and Analysis, Part 2 from Stanford UniversityShortest Paths Revisited, NP-Complete Problems and What To Do About Themfrom Stanford UniversityGraph Search, Shortest Paths, and Data Structures from Stanford UniversityLanguage, Proof and Logic from Stanford UniversityMobile Application Experiences from Massachusetts Institute of TechnologyComputation Structures 2: Computer Architecture from Massachusetts Institute of TechnologyComputational Thinking for Modeling and Simulation from Massachusetts Institute of TechnologyAdvanced Software Construction in Java from Massachusetts Institute of TechnologyMobile Application Experiences Part 3: Building Mobile Apps from Massachusetts Institute of TechnologyFoundations of Data Science: Prediction and Machine Learning from University of California, BerkeleyBlockchain Technology from University of California, BerkeleyBitcoin and Cryptocurrencies from University of California, BerkeleyData Structures and Software Design from University of PennsylvaniaAlgorithm Design and Analysis from University of PennsylvaniaSoftware Development Fundamentals from University of PennsylvaniaIntroduction to Neurohacking In R from Johns Hopkins UniversityNetworking and Security in iOS Applications from University of California, IrvineToward the Future of iOS Development with Swift from University of California, IrvineGames, Sensors and Media from University of California, IrvineJava Programming: Build a Recommendation System from Duke UniversityIntroduction to Machine Learning from Duke UniversityComputer Science: Algorithms, Theory, and Machines from Princeton UniversityIntroduction to Graduate Algorithms from Georgia Institute of TechnologySoftware Analysis & Testing from Georgia Institute of TechnologyDatabase Systems Concepts & Design from Georgia Institute of TechnologyDatabase Systems Concepts and Design from Georgia Institute of TechnologyAnimation and CGI Motion from Columbia UniversityData Analytics Foundations for Accountancy II from University of Illinois at Urbana-ChampaignInternet of Things: Sensing and Actuation From Devices from University of California, San DiegoData Structures: An Active Learning Approach from University of California, San DiegoHow Virtual Reality Works from University of California, San DiegoMinecraft, Coding and Teaching from University of California, San DiegoGraph Algorithms from University of California, San DiegoData Structures Fundamentals from University of California, San DiegoString Processing and Pattern Matching Algorithms from University of California, San DiegoMachine Learning Fundamentals from University of California, San DiegoAlgorithmic Design and Techniques from University of California, San DiegoCreating Virtual Reality (VR) Apps from University of California, San DiegoBuilding a Cybersecurity Toolkit from University of WashingtonFinding Your Cybersecurity Career Path from University of WashingtonProgramming Languages, Part C from University of WashingtonCybersecurity: The CISO's View from University of WashingtonProgramming Languages, Part B from University of WashingtonMathematics for Computer Science from University of London International ProgrammesBlockchain Basics from University at BuffaloBlockchain Platforms from University at BuffaloDecentralized Applications (Dapps) from University at BuffaloSmart Contracts from University at Buffalo算法设计与分析 Design and Analysis of Algorithms from Peking University面向对象技术高级课程(The Advanced Object-Oriented Technology) from Peking UniversityHow to Code: Complex Data from The University of British ColumbiaSoftware Construction: Object-Oriented Design from The University of British ColumbiaSoftware Construction: Data Abstraction from The University of British ColumbiaTesting with Agile from University of VirginiaRunning Product Design Sprints from University of VirginiaNoSQL Database Systems from Arizona State UniversityMoving to the Cloud from University of MelbourneSQL for Data Science from University of California, DavisLAFF – On Programming for Correctness from The University of Texas at Austin LaTeX (Introduction to LaTeX) from Higher School of EconomicsSoftware Development Processes and Methodologies from University of MinnesotaAgile Software Development from University of MinnesotaLean Software Development from University of MinnesotaAndroid App Components - Services, Local IPC, and Content Providers from Vanderbilt UniversityEngineering Maintainable Android Apps from Vanderbilt UniversityJava for Android from Vanderbilt UniversityAndroid App Components - Intents, Activities, and Broadcast Receivers from Vanderbilt UniversityDeveloping Android Apps with App Inventor from The Hong Kong University of Science and TechnologyFront-End Web Development with React from The Hong Kong University of Science and TechnologyServer-side Development with NodeJS, Express and MongoDB from The Hong Kong University of Science and TechnologyFront-End JavaScript Frameworks: Angular from The Hong Kong University of Science and TechnologyMultiplatform Mobile App Development with NativeScript from The Hong Kong University of Science and TechnologyFront-End Web UI Frameworks and Tools: Bootstrap 4 from The Hong Kong University of Science and TechnologyMultiplatform Mobile App Development with React Native from The Hong Kong University of Science and TechnologyMultiplatform Mobile App Development with Web Technologies: Ionic and Cordova from The Hong Kong University of Science and TechnologyGlobal Software Development from Delft University of TechnologyAutomated Software Testing: Model and State-based Testing from Delft University of TechnologyAutomated Software Testing: Unit Testing, Coverage Criteria and Design for Testability from Delft University of Technology Android- from Moscow Institute of Physics and Technology HTML CSS from Moscow Institute of Physics and Technology iOS- from Moscow Institute of Physics and TechnologyBuilding Arduino robots and devices from Moscow Institute of Physics and Technology - Golang, 2 from Moscow Institute of Physics and TechnologyNoSQL systems from Universidad Nacional Autónoma de MéxicoRelational database systems from Universidad Nacional Autónoma de MéxicoFundamentos de Android from Universidad Nacional Autónoma de MéxicoImplementation of Data Structures from Indian Institute of Technology BombayFoundations of Data Structures from Indian Institute of Technology BombayProfessional Android App Development from Galileo University : from Tsinghua UniversityEnterprise Software Lifecycle Management from National Research Nuclear University MEPhI from National Research Nuclear University MEPhICloud Computing from Indian Institute of Technology, KharagpurThe Software Architect Code: Building the Digital World from Universidad Carlos iii de MadridIntroduction to Java Programming: Fundamental Data Structures and Algorithms from Universidad Carlos iii de MadridReviews & Metrics for Software Improvements from University of AlbertaObject-Oriented Design from University of AlbertaSoftware Architecture from University of AlbertaService-Oriented Architecture from University of AlbertaDesign Patterns from University of AlbertaWeb Connectivity and Security in Embedded Systems from EIT DigitalIntroduction to Architecting Smart IoT Devices from EIT DigitalSoftware Architecture for the Internet of Things from EIT DigitalArchitecting Smart IoT Devices from EIT DigitalAndroid Basics: Networking from GoogleScalable Microservices with Kubernetes from GoogleDeveloping Android Apps with Kotlin from GoogleIntro to Progressive Web Apps from GoogleGoogle Maps APIs from GoogleAndroid Basics: User Input from GoogleVR Software Development from GoogleFirebase Essentials For Android from GoogleMaterial Design for Android Developers from GoogleOffline Web Applications from GoogleAdvanced Android App Development from GoogleClient-Server Communication from GoogleIntro to Data Structures and Algorithms from GoogleAndroid Performance from GoogleAndroid Basics: User Interface from GoogleGoogle Cloud Platform Fundamentals for AWS Professionals from Google CloudAndroid Basics: Button Clicks from GoogleApplied Machine Learning from MicrosoftIntroduction to TypeScript 2 from MicrosoftAdvanced CSS Concepts from MicrosoftOptimizing Performance for SQL Based Applications from MicrosoftBuilding Functional Prototypes using Node.js from MicrosoftDeveloping Intelligent Apps and Bots from MicrosoftDesigning Data Platform Solutions from MicrosoftAngularJS: Advanced Framework Techniques from MicrosoftCreating Programmatic SQL Database Objects from MicrosoftImplementing In-Memory SQL Database Objects from MicrosoftApplication Design Considerations: An Inclusive Approach from MicrosoftIntroduction to C# from MicrosoftAlgorithms and Data Structures from MicrosoftDeveloping SQL Databases from MicrosoftBuilding Interactive Prototypes using JavaScript from MicrosoftAngularJS: Framework Fundamentals from MicrosoftAlgorithms and Data Structures in C# from MicrosoftBuild a Modern Computer from First Principles: Nand to Tetris Part II (project-centered course) from Hebrew University of JerusalemProgrammation iOS (partie I) from Sorbonne UniversitésProgrammation iOS (partie II) from Sorbonne UniversitésIntroduction to Data Structures from University of AdelaideFundamentals of Machine Learning from Santa Fe InstituteIntroduction to Computation Theory from Santa Fe InstituteCloud Computing Security from University of Colorado SystemDetecting and Mitigating Cyber Threats and Attacks from University of Colorado SystemIntroduction to Web Cartography: Part 1 from ETH ZurichSymmetric Cryptography from University of Colorado SystemPacket Switching Networks and Algorithms from University of Colorado SystemAsymmetric Cryptography and Key Management from University of Colorado SystemFundamentals of Network Communication from University of Colorado SystemHacking and Patching from University of Colorado SystemPeer-to-Peer Protocols and Local Area Networks from University of Colorado SystemDesign and Analyze Secure Networked Systems from University of Colorado SystemSRS Documents: Requirements and Diagrammatic Notations from University of Colorado SystemIntermediate Object-Oriented Programming for Unity Games from University of Colorado SystemLinux Server Management and Security from University of Colorado SystemRequirements Specifications: Goals and Conflict Analysis from University of Colorado SystemIntroduction to C# Programming and Unity from University of Colorado SystemRequirements Gathering for Secure Software Development from University of Colorado SystemMore C# Programming and Unity from University of Colorado SystemHomeland Security & Cybersecurity Connection - It's Not About the Terroristsfrom University of Colorado SystemRequirements Elicitation: Artifact and Stakeholder Analysis from University of Colorado SystemSoftware Design Threats and Mitigations from University of Colorado SystemData Structures and Design Patterns for Game Developers from University of Colorado SystemSoftware Requirements Prioritization: Risk Analysis from University of Colorado SystemBasic Cryptography and Programming with Crypto API from University of Colorado SystemIntroduction to DevOps: Transforming and Improving Operations from Linux FoundationMachine Learning for Musicians and Artists from Goldsmiths, University of LondonIntroduction to Cloud Infrastructure Technologies from Linux Foundation2D Game Development with libGDX from AmazonIntroduction to Kubernetes from Linux FoundationCybersecurity and the X-Factor from University System of GeorgiaCybersecurity and the Internet of Things from University System of GeorgiaCybersecurity and Privacy in the IoT from Curtin UniversityMobile Design and Usability for Android from FacebookWeb App Development with the Power of Node.js from Technische Universität München (Technical University of Munich)IoT System Architecture: Design and Evaluation from Waseda UniversityMobile Design and Usability for iOS from FacebookOrientação a Objetos com Java from Instituto Tecnológico de AeronáuticaGuided Tour of Machine Learning in Finance from New York University (NYU)Network Security from Rochester Institute of TechnologyOverview of Advanced Methods of Reinforcement Learning in Finance from New York University (NYU)Cybersecurity Risk Management from Rochester Institute of TechnologyComputer Forensics from Rochester Institute of TechnologyTeamwork & Collaboration from Rochester Institute of TechnologyCybersecurity Fundamentals from Rochester Institute of TechnologyAdvanced Algorithmics and Graph Theory with Python from Institut Mines-TélécomUML Class Diagrams for Software Engineering from KU Leuven UniversityFundamentals of Machine Learning in Finance from New York University (NYU)Real-Time Cyber Threat Detection and Mitigation from New York University (NYU)Gameplay Programming for Video Game Designers from Rochester Institute of TechnologyProgramming for Everyone – An Introduction to Visual Programming Languages from Weizmann Institute of ScienceIntrodução ao Teste de Software from Universidade de São Paulo Androidfrom ITMO UniversityConcurrency from AdaCore UniversityHow to Win Coding Competitions: Secrets of Champions from ITMO UniversityFormal Software Verification from University System of MarylandCloud Computing Infrastructure from University System of MarylandSoftware Testing Management from University System of MarylandCloud Computing Management from University System of MarylandDesarrollo de Aplicaciones Mobile Multiplataforma con Nativescript, Angular y Redux from Universidad AustralSoftware Testing Fundamentals from University System of MarylandCloud Computing for Enterprises from University System of MarylandSQL for Data AnalysisDeploying Applications with HerokuHacker101 from HackerOneVR Scenes and ObjectsDesigning RESTful APIsVR Platforms & ApplicationsSwift for DevelopersFundamentals of Parallelism on Intel Architecture from IntelVR DesignIntro to TensorFlow for Deep LearningiOS Persistence and Core DataHow to Make an iOS AppAndroid Basics: Data StorageFoundations of Machine Learning from BloombergiOS Networking with SwiftFundamentals of Red Hat Enterprise Linux from Red HatUIKit FundamentalsFundamentals of Containers, Kubernetes, and Red Hat OpenShift from Red HatIntroduction: Elements of Microgame Design from Worcester Polytechnic InstituteLearn Backbone.jsDiseño de Sistemas de información gerencial para Internet con MySQL / PHP y Joomla from Universidad del RosarioDynamic Web Applications with SinatraDeveloping Android AppsAn Introduction to Practical Deep Learning from InteliOS Design PatternsBuilding iOS InterfacesHow to create in AndroidAdvanced (139)Machine Learning Foundations: A Case Study Approach from University of Washington ★★★★☆(38)[New] Sample-based Learning Methods from University of Alberta[New] Fundamentals of Reinforcement Learning from University of AlbertaMachine Learning: Regression from University of Washington ★★★★★(18)Machine Learning for Data Science and Analytics from Columbia University★★★☆☆(15)Probabilistic Graphical Models 1: Representation from Stanford University★★★★☆(14)Intro to Deep Learning from Google ★★☆☆☆(13)Creative Applications of Deep Learning with TensorFlowMachine Learning With Big Data from University of California, San Diego★★☆☆☆(12)Machine Learning for Trading from Georgia Institute of Technology ★★★☆☆(11)Hardware Security from University of Maryland, College Park ★★★☆☆(11)Bitcoin and Cryptocurrency Technologies from Princeton University★★★★☆(10)Introduction to Artificial Intelligence from Stanford University ★★★★★(9)Computational Neuroscience from University of Washington ★★★★☆(8)Reinforcement Learning from Brown University ★★☆☆☆(6)Machine Learning: Classification from University of Washington ★★★★★(6)Intro to Parallel Programming from Nvidia ★★★★☆(6)Advanced Operating Systems from Georgia Institute of Technology ★★★★★(5)Enabling Technologies for Data Science and Analytics: The Internet of Thingsfrom Columbia University ★☆☆☆☆(5)Interactive 3D Graphics from Autodesk ★★★★★(5)Machine Learning from Georgia Institute of Technology ★★★★★(4)Applied Cryptography from University of Virginia ★★★★☆(4)Parallel programming from École Polytechnique Fédérale de Lausanne★★★★☆(4)Introduction to Computer Architecture from Carnegie Mellon University★★★★★(4)Probabilistic Graphical Models 2: Inference from Stanford University★★★★☆(3)Practical Predictive Analytics: Models and Methods from University of Washington ★★☆☆☆(3)Machine Learning: Clustering & Retrieval from University of Washington★★★★★(3)Regression Modeling in Practice from Wesleyan University ★★★★☆(3)Quantitative Formal Modeling and Worst-Case Performance Analysis from EIT Digital ★★★☆☆(3)Nearest Neighbor Collaborative Filtering from University of Minnesota★★☆☆☆(2)High Performance Computer Architecture from Georgia Institute of Technology★★★★★(1)Computability, Complexity & Algorithms from Georgia Institute of Technology★★★★★(1)Computational Photography from Georgia Institute of Technology ★★★★☆(1)Introduction to Operating Systems from Georgia Institute of Technology★★★★★(1)Artificial Intelligence (AI) from Columbia University ★☆☆☆☆(1)Cloud Computing Applications, Part 2: Big Data and Applications in the Cloudfrom University of Illinois at Urbana-Champaign ★★★★☆(1)Relational Database Support for Data Warehouses from University of Colorado System ★★☆☆☆(1)Practical Deep Learning For Coders, Part 1 from fast.ai ★★★★★(1)Real-Time Audio Signal Processing in Faust from Stanford UniversityImproving Deep Neural Networks: Hyperparameter tuning, Regularization and Optimization from deeplearning.aiConvolutional Neural Networks from deeplearning.ai6.S094: Deep Learning for Self-Driving Cars from Massachusetts Institute of Technology6.S191: Introduction to Deep Learning from Massachusetts Institute of TechnologyComputation Structures 3: Computer Organization from Massachusetts Institute of TechnologyApplied Machine Learning in Python from University of MichiganMachine Learning from Georgia Institute of TechnologyCompilers: Theory and Practice from Georgia Institute of TechnologyNetwork Security from Georgia Institute of TechnologyCyber-Physical Systems Security from Georgia Institute of TechnologyGT - Refresher - Advanced OS from Georgia Institute of TechnologyHigh Performance Computing from Georgia Institute of TechnologyArtificial Intelligence from Georgia Institute of TechnologyKnowledge-Based AI: Cognitive Systems from Georgia Institute of TechnologyMachine Learning from Georgia Institute of TechnologyIntro to Information Security from Georgia Institute of TechnologyCyber-Physical Systems Design & Analysis from Georgia Institute of TechnologyMachine Learning from Columbia UniversityNP-Complete Problems from University of California, San DiegoParallel Programming in Java from Rice UniversityConcurrent Programming in Java from Rice UniversityDistributed Programming in Java from Rice UniversityInformation Security: Context and Introduction from University of London International ProgrammesQuantum Machine Learning from University of TorontoState Estimation and Localization for Self-Driving Cars from University of TorontoBasic Modeling for Discrete Optimization from University of MelbourneAdvanced Modeling for Discrete Optimization from University of MelbourneSolving Algorithms for Discrete Optimization from University of MelbourneMATLAB et Octave pour débutants from École Polytechnique Fédérale de LausanneNature, in Code: Biology in JavaScript from École Polytechnique Fédérale de Lausanne from Higher School of Economics from Higher School of EconomicsDeep Learning in Computer Vision from Higher School of Economics from Higher School of EconomicsIntroduction to Formal Concept Analysis from Higher School of EconomicsPractical Reinforcement Learning from Higher School of EconomicsAddressing Large Hadron Collider Challenges by Machine Learning from Higher School of EconomicsIntroduction to Deep Learning from Higher School of EconomicsBayesian Methods for Machine Learning from Higher School of EconomicsMatrix Factorization and Advanced Techniques from University of MinnesotaRecommender Systems: Evaluation and Metrics from University of MinnesotaIntroduction to Recommender Systems: Non-Personalized and Content-Basedfrom University of MinnesotaEmbedded Software and Hardware Architecture from University of Colorado BoulderModeling and Debugging Embedded Systems from University of Colorado BoulderRazonamiento artificial from Universidad Nacional Autónoma de MéxicoSesenta años de inteligencia artificial from Universidad Nacional Autónoma de México人工智慧:搜尋方法與邏輯推論 (Artificial Intelligence - Search & Logic) from National Taiwan University機器學習基石下 (Machine Learning Foundations)---Algorithmic Foundationsfrom National Taiwan University大数据机器学习|Big Data Machine Learning from Tsinghua UniversityDiscrete Mathematics from Shanghai Jiao Tong UniversityIntroducción a la visión por computador: desarrollo de aplicaciones con OpenCV from Universidad Carlos iii de MadridSystem Validation (4): Modelling Software, Protocols, and other behaviourfrom EIT DigitalSystem Validation (2): Model process behaviour from EIT DigitalSystem Validation: Automata and behavioural equivalences from EIT DigitalSystem Validation (3): Requirements by modal formulas from EIT DigitalEmbedded Hardware and Operating Systems from EIT DigitalApproximation Algorithms from EIT DigitalLearn TensorFlow and deep learning, without a Ph.D. from GoogleMachine Learning Crash Course with TensorFlow APIs from GoogleInfrastructure as Code from MicrosoftDeep Learning Explained from MicrosoftDevOps for Databases from MicrosoftIntroduction to Artificial Intelligence (AI) from MicrosoftDevOps Practices and Principles from MicrosoftDevOps Testing from MicrosoftSparse Representations in Signal and Image Processing: Fundamentals from Technion - Israel Institute of TechnologySparse Representations in Image Processing: From Theory to Practice from Technion - Israel Institute of TechnologyCyber-Physical Systems: Modeling and Simulation from University of California, Santa CruzStatistical Machine Learning from Carnegie Mellon UniversityCryptographic Hash and Integrity Protection from University of Colorado SystemCryptography and Information Theory from University of Colorado SystemClassical Cryptosystems and Core Concepts from University of Colorado SystemIntroduction to Hyperledger Blockchain Technologies from Linux FoundationIntroduction to OpenStack from Linux FoundationIntroduction to Cloud Foundry and Cloud Native Software Architecture from Linux FoundationApproximation Algorithms Part II from École normale supérieureMathematics for Machine Learning: Multivariate Calculus from Imperial College LondonMathematics for Machine Learning: PCA from Imperial College LondonReliable Distributed Algorithms, Part 2 from KTH Royal Institute of TechnologyMathematics for Machine Learning: Linear Algebra from Imperial College LondonMulti-Object Tracking for Automotive Systems from Chalmers University of TechnologyComputer System Design: Advanced Concepts of Modern Microprocessorsfrom Chalmers University of TechnologyDeep Learning with Python and PyTorch from IBMDeep Learning with Tensorflow from IBMReinforcement Learning in Finance from New York University (NYU)Deep Learning for Natural Language Processing from University of OxfordCutting Edge Deep Learning For Coders, Part 2 from fast.aiCloud Computing Security from University System of MarylandIntroduction to Machine Learning for Coders! from fast.aiConvolutional Neural Networks in TensorFlow from deeplearning.aiNatural Language Processing in TensorFlow from deeplearning.aiDeep Learning Summer SchoolContinuous Integration and DeploymentAccess Controls from (ISC)²Big Data Applications: Machine Learning at Scale from YandexIdentifying, Monitoring, and Analyzing Risk and Incident Response and Recovery from (ISC)²Security Operations and Administration from (ISC)²Networks and Communications Security from (ISC)²Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning from deeplearning.aiSystems and Application Security from (ISC)²

August 7, 2019 · 26 min · jiezi

借助URLOS快速安装WordPress

简介WordPress是一个以PHP和MySQL为平台的自由开源的博客软件和内容管理系统。WordPress具有插件架构和模板系统。截至2018年4月,排名前1000万的网站超过30.6%使用WordPress。WordPress是最受欢迎的网站内容管理系统。WordPress是当前因特网上最流行的博客系统。 今天我们介绍一种更快速的安装方法,那就是通过URLOS一键安装WordPress。urlos是什么? URLOS是一个云主机管理软件,基于Docker容器技术打包和运行应用,包含负载均衡和故障转移等高级功能,可自动识别机器和云应用的故障并将云应用转移至可用的机器上,单机故障并不影响业务开展。 你可以使用以下命令安装URLOS: curl -LO www.urlos.com/iu && sh iu在此不讨论URLOS的使用方法,感兴趣的朋友请自行搜索,我们直接来看URLOS如何快速安装WordPress: 安装流程1. 登录URLOS系统后台,在应用市场中搜索“WordPress”,找到之后,直接点击安装按钮 2.填写服务名称、选择运行节点、选择智能部署 3.填写域名:www.aaa.com(这里填写自己的域名) 4.设置数据库 然后点击“提交”按钮,等待部署完成;

July 10, 2019 · 1 min · jiezi

Kafka集群部署指南

一、前言1、Kafka简介Kafka是一个开源的分布式消息引擎/消息中间件,同时Kafka也是一个流处理平台。Kakfa支持以发布/订阅的方式在应用间传递消息,同时并基于消息功能添加了Kafka Connect、Kafka Streams以支持连接其他系统的数据(Elasticsearch、Hadoop等) Kafka最核心的最成熟的还是他的消息引擎,所以Kafka大部分应用场景还是用来作为消息队列削峰平谷。另外,Kafka也是目前性能最好的消息中间件。 2、Kafka架构 在Kafka集群(Cluster)中,一个Kafka节点就是一个Broker,消息由Topic来承载,可以存储在1个或多个Partition中。发布消息的应用为Producer、消费消息的应用为Consumer,多个Consumer可以促成Consumer Group共同消费一个Topic中的消息。 概念/对象简单说明BrokerKafka节点Topic主题,用来承载消息Partition分区,用于主题分片存储Producer生产者,向主题发布消息的应用Consumer消费者,从主题订阅消息的应用Consumer Group消费者组,由多个消费者组成3、准备工作1、Kafka服务器准备3台CentOS服务器,并配置好静态IP、主机名 服务器名IP说明kafka01192.168.88.51Kafka节点1kafka02192.168.88.52Kafka节点2kafka03192.168.88.53Kafka节点3软件版本说明 项说明Linux ServerCentOS 7Kafka2.3.02、ZooKeeper集群Kakfa集群需要依赖ZooKeeper存储Broker、Topic等信息,这里我们部署三台ZK 服务器名IP说明zk01192.168.88.21ZooKeeper节点zk02192.168.88.22ZooKeeper节点zk03192.168.88.23ZooKeeper节点部署过程参考:https://ken.io/note/zookeeper... 二、部署过程1、应用&数据目录#创建应用目录mkdir /usr/kafka#创建Kafka数据目录mkdir /kafkamkdir /kafka/logschmod 777 -R /kafka2、下载&解压Kafka官方下载地址:https://kafka.apache.org/down...这次我下载的是2.3.0版本 #创建并进入下载目录mkdir /home/downloadscd /home/downloads#下载安装包wget http://mirrors.tuna.tsinghua.edu.cn/apache/kafka/2.3.0/kafka_2.12-2.3.0.tgz #解压到应用目录tar -zvxf kafka_2.12-2.3.0.tgz -C /usr/kafkakafka_2.12-2.3.0.tgz 其中2.12是Scala编译器的版本,2.3.0才是Kafka的版本3、Kafka节点配置#进入应用目录cd /usr/kafka/kafka_2.12-2.3.0/#修改配置文件vi config/server.properties通用配置配置日志目录、指定ZooKeeper服务器 # A comma separated list of directories under which to store log fileslog.dirs=/kafka/logs# root directory for all kafka znodes.zookeeper.connect=192.168.88.21:2181,192.168.88.22:2181,192.168.88.23:2181分节点配置Kafka01broker.id=0#listeners=PLAINTEXT://:9092listeners=PLAINTEXT://192.168.88.51:9092Kafka02broker.id=1#listeners=PLAINTEXT://:9092listeners=PLAINTEXT://192.168.88.52:9092Kafka03broker.id=2#listeners=PLAINTEXT://:9092listeners=PLAINTEXT://192.168.88.53:90924、防火墙配置#开放端口firewall-cmd --add-port=9092/tcp --permanent#重新加载防火墙配置firewall-cmd --reload5、启动Kafka#进入kafka根目录cd /usr/kafka/kafka_2.12-2.3.0/#启动/bin/kafka-server-start.sh config/server.properties &#启动成功输出示例(最后几行)[2019-06-26 21:48:57,183] INFO Kafka commitId: fc1aaa116b661c8a (org.apache.kafka.common.utils.AppInfoParser)[2019-06-26 21:48:57,183] INFO Kafka startTimeMs: 1561531737175 (org.apache.kafka.common.utils.AppInfoParser)[2019-06-26 21:48:57,185] INFO [KafkaServer id=0] started (kafka.server.KafkaServer)三、Kafka测试1、创建Topic在kafka01(Broker)上创建测试Tpoic:test-ken-io,这里我们指定了3个副本、1个分区 ...

July 3, 2019 · 1 min · jiezi

Hexo搭建个人博客系列一为什么选择Hexo

文/方子龙 一天不码字就剁手的程序猿 1.简介花了几天搭建了个网站,先上链接,欢迎来访:方子龙的个人博客 现在市面上的博客很多,如CSDN,博客园,简书等平台,可以直接在上面发表,用户交互做的好,写的文章百度也能搜索的到。缺点是比较不自由,会受到平台的各种限制和恶心的广告。 而自己购买域名和服务器,搭建博客的成本实在是太高了,不光是说这些购买成本,单单是花力气去自己搭这么一个网站,还要定期的维护它,对于我们大多数人来说,实在是没有这样的精力和时间。 那么就有第三种选择,直接在github page平台上托管我们的博客。这样就可以安心的来写作,又不需要定期维护,而且hexo作为一个快速简洁的博客框架,用它来搭建博客真的非常容易。 我第一次接触Hexo是2018年,我开始是想自己用SpringBoot写一个博客系统,后来在实践的过程中,需要考虑几件事情: 前端页面的实现后端功能的实现数据库的维护服务器的维护考虑购买服务器的费用,还有前端功能的实现,这样的周期就拖得很长,也就没有去实践了。 经过一段时间的收集资料,发现有另外几种方案的实现,Wordpress, Hexo, Jekyll等, 既减少了服务器上的运维,也可以拥有好看的前端效果,而且整个搭建过程也是很简单的。那我们先来看看方案的对比,拓展一下眼界。 2. 方案对比【1】WordPress是什么?引用百度百科 WordPress是使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站。WordPress有许多第三方开发的免费模板,安装方式简单易用。WordPress需要会PHP和服务器,所以对于新手来说,还是有门槛的。 【2】Jekyll是什么? 引用自官网:Jekyll 是一个简单的博客形态的静态站点生产机器。它有一个模版目录,其中包含原始文本格式的文档,通过一个转换器(如 Markdown)和我们的 Liquid 渲染器转化成一个完整的可发布的静态网站,你可以发布在任何你喜爱的服务器上。Jekyll 也可以运行在 GitHub Page 上,也就是说,你可以使用 GitHub 的服务来搭建你的项目页面、博客或者网站,而且是完全免费的。Jekyll需要的环境如下: RubyRubyGemsNodeJS或其他 JavaScript 运行环境(如果还没安装NodeJS的,可以参照我写的另一篇文章Mac下安装nvm和NodeJS)Python2.7(或2.7以上版本)看着这些环境,三哥就不想沾染了。 【3】Hexo是什么? Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。Hexo的主题样式也有很多好看的,而且github都有star上万的。说明还是很受欢迎的。Hexo是基于Nodejs,目前也比较火,基于Nodejs搭建的脚手架,对于前后端还是很友好的。Hexo官方中文文档 3. 总结采用Hexo博客框架,来快速搭建属于自己的博客系统,在托管到Pages上去,可以省去服务器维护的时间和精力。

June 17, 2019 · 1 min · jiezi

Ruby-比特币开发教程汇总

Mixin Network 是一个免费的 极速的端对端加密数字货币交易系统. Mixin network 官方资源汇总 课程简介创建一个机器人Ruby比特币开发教程: 机器人接受比特币并立即退还用户Ruby比特币开发教程: 创建比特币钱包Ruby 买卖Bitcoin:ExinCore API 实时兑换Ruby 买卖Bitcoin:在自由市场Ocean.One挂单买卖Ruby 买卖任意ERC20 token:在自由市场Ocean.One挂单买卖其他编程语言汇总Python 比特币开发教程 Node.js 比特币开发教程 Java 比特币开发教程 Golang 比特币开发教程 C# 比特币开发教程

May 29, 2019 · 1 min · jiezi

通过-Ruby-买卖Bitcoin使用开放交易所OceanOne

上一章介绍了Exincore,你可以1秒完成资产的市价买卖。如果你想限定价格买卖,或者买卖一些exincore不支持的资产,你需要OceanOne。 方案二: 挂单Ocean.One交易所Ocean.one是基于Mixin Network的去中心化交易所,它性能一流。你可以在OceanOne上交易任何资产,只需要将你的币转给OceanOne, 将交易信息写在交易的memo里,OceanOne会在市场里列出你的交易需求,交易成功后,会将目标币转入到你的MixinNetwork帐上,它有三大特点与优势: 不需要在OceanOne注册不需要存币到交易所支持所有Mixin Network上能够转账的资产,所有的ERC20 EOS代币。预备知识:你先需要创建一个机器人, 方法在 教程一. 安装依赖包我们需要依赖 msgpack and mixin-bot ,第四章 已经做过介绍, 你应该先安装过它了. 充币到 Mixin Network, 并读出它的余额.此处演示用 USDT购买BTC 或者 用BTC购买USDT。交易前,先检查一下钱包地址。完整的步骤如下: 检查比特币或USDT的余额,钱包地址。并记下钱包地址。从第三方交易所或者你的冷钱包中,将币充到上述钱包地址。再检查一下币的余额,看到帐与否。(比特币的到帐时间是5个区块的高度,约100分钟)。比特币与USDT的充值地址是一样的。 if cmd == "aw" assetsInfo = walletAccount.read_assets() p "--------The Wallet Assets List-----------------" assetsInfo["data"].each { |x| puts x["symbol"] + " " + x["balance"] + " " + x["public_key"] + x["account_name"] + " " + x["account_tag"]} p "----------End of Wallet Assets --------------"end取得Ocean.one的市场价格信息如何来查询Ocean.one市场的价格信息呢?你要先了解你交易的基础币是什么,如果你想买比特币,卖出USDT,那么基础货币就是USDT;如果你想买USDT,卖出比特币,那么基础货币就是比特币. if ocmd == "1" Utils.OceanOneMarketPriceRequest(BTC_ASSET_ID, USDT_ASSET_ID)enddef self.OceanOneMarketPriceRequest(asset_id, base_asset_id) full_url = "https://events.ocean.one/markets/" + asset_id + "-" + base_asset_id + "/book" data = HTTP.get(full_url).body body = "" redData = data.readpartial while redData != nil body = body + redData redData = data.readpartial end result = ActiveSupport::JSON.decode(body).with_indifferent_access result["data"]["data"]["asks"].each { |x| puts x["side"] + " " + x["price"] + " " + x["amount"] + " " + x["funds"] } result["data"]["data"]["bids"].each { |x| puts x["side"] + " " + x["price"] + " " + x["amount"] + " " + x["funds"] }end交易前,创建一个Memo!在第二章里,Ruby比特币开发教程: 机器人接受比特币并立即退还用户, 我们学习过转帐,这儿我们介绍如何告诉Ocean.one,我们给它转帐的目的是什么,信息全部放在memo里. ...

May 27, 2019 · 3 min · jiezi

如何用-Ruby-买卖Bitcoin

方案一: 通过ExinCore API进行币币交易Exincore 提供了基于Mixin Network的币币交易API. 你可以支付USDT给ExinCore, ExinCore会以最低的价格,最优惠的交易费将你购买的比特币转给你, 每一币交易都是匿名的,并且可以在区块链上进行验证,交易的细节只有你与ExinCore知道! ExinCore 也不知道你是谁,它只知道你的UUID. 预备知识:你先需要创建一个机器人, 方法在 教程一. 安装依赖包正如教程一里我们介绍过的, 我们需要依赖 mixin-bot, 你应该先安装过它了, 这儿我们再安装 easy-uuid, msgpack 两个软件包. gem install msgpack gem install easy-uuid充币到 Mixin Network, 并读出它的余额.ExinCore可以进行BTC, USDT, EOS, ETH 等等交易, 这儿演示如果用 USDT购买BTC 或者 用BTC购买USDT, 交易前,先检查一下钱包地址!完整的步骤如下: 检查比特币或USDT的余额,钱包地址。并记下钱包地址。从第三方交易所或者你的冷钱包中,将币充到上述钱包地址。再检查一下币的余额,看到帐与否。(比特币的到帐时间是5个区块的高度,约100分钟)。请注意,比特币与USDT的地址是一样的。 if cmd == "aw" assetsInfo = walletAccount.read_assets() p "--------The Wallet Assets List-----------------" assetsInfo["data"].each { |x| puts x["symbol"] + " " + x["balance"] + " " + x["public_key"] + x["account_name"] + " " + x["account_tag"]} p "----------End of Wallet Assets --------------"end查询ExinCore市场的价格信息如果来查询ExinCore市场的价格信息呢?你要先了解你交易的基础币是什么,如果你想买比特币,卖出USDT,那么基础货币就是USDT;如果你想买USDT,卖出比特币,那么基础货币就是比特币. ...

May 25, 2019 · 3 min · jiezi

Ruby-比特币开发教程-创建比特币钱包

我们已经创建过一个回复消息的机器人和一个能自动支付比特币的机器人. 通过本教程的学习,你可以学到如下内容如何创建一个比特币钱包.如何读取比特币钱包的余额.如何支付比特币并即时确认.如何将Mixin Network的比特币提现到你的冷钱包或第三方交易所.前期准备:你要有一个Mixin Network账户。下面的代码创建一个帐号,并写到csv文件里。 if File.file?(WALLET_NAME) p "mybitcoin_wallet.csv has already existed !" nextendyaml_hash = YAML.load_file('./config.yml')MixinBot.client_id = yaml_hash["MIXIN_CLIENT_ID"]MixinBot.session_id = yaml_hash["MIXIN_SESSION_ID"]MixinBot.client_secret = yaml_hash["MIXIN_CLIENT_SECRET"]MixinBot.pin_token = yaml_hash["MIXIN_PIN_TOKEN"]MixinBot.private_key = yaml_hash["MIXIN_PRIVATE_KEY"]access_token = MixinBot.api.access_token("GET","/","")rsa_key = OpenSSL::PKey::RSA.new(1024)private_key = rsa_key.to_pem()p private_keypublic_key = rsa_key.public_key.to_pemsecret_client = public_key.sub("-----BEGIN PUBLIC KEY-----\n","").sub("\n-----END PUBLIC KEY-----\n","")reqInfo = MixinBot.api.create_user("ruby bot",secret_client)p reqInfo["data"]["pin_token"]p reqInfo["data"]["user_id"]p reqInfo["data"]["session_id"]CSV.open(WALLET_NAME, "wb") do |csv| csv << [private_key, reqInfo["data"]["pin_token"], reqInfo["data"]["session_id"], reqInfo["data"]["user_id"]]end上面的语句会在本地创建一个RSA密钥对,然后调用Mixin Network来创建帐号,最后保存帐号信息到csv文件. 现在你需要小心保管好你的帐号信息,在读取该账户的比特币资产余额或者进行其他操作时,将需要用到这些信息. 给新建的帐号创建一个比特币钱包新账号并不默认内置比特币钱包, 现在读一下比特币余额就可以创建一个比特币钱包。 if cmd == "2" table = CSV.read(WALLET_NAME) MixinBot.client_id = table[0][3] MixinBot.session_id = table[0][2] MixinBot.pin_token = table[0][1] MixinBot.private_key = table[0][0] botAssetsInfo = MixinBot.api.read_asset(BTC_ASSET_ID) p botAssetsInfo p "The BTC wallet address is " + botAssetsInfo["data"]["public_key"] p "The BTC wallet balance is " + botAssetsInfo["data"]["balance"]end创建的帐号的比特币资产详细信息如下,其中public key就是比特币的存币地址: ...

May 22, 2019 · 3 min · jiezi

使用-Nodejs-在开放交易所OceanOne上挂单买卖奔驰币

在上一课中,我们介绍了如何在OceanOne交易比特币。OceanOne支持交易任何Mixin Network上的token,包括所有的ERC20和EOS token,不需要任何手续和费用,直接挂单即可。下面介绍如何将将一个ERC20 token挂上OceanOne交易。掌握了ERC20代币的交易方法,就可以交易任何其他Mixin Network代币了。 此处我们用一个叫做Benz的ERC20 token为例。这个token已经被充值进Mixin Network,你可以在区块链浏览器看到这个token在Mixin Network内部的总数和交易 预备知识:先将Ben币存入你的钱包,然后使用getAssets API读取它的UUID. 取得该币的UUID调用 getAssets API 会返回json数据, 如: asset_id 币的UUID.public_key 该币的当前钱包的地址.symbol 币的名称. 如: Benz.if ( args.type === TYPE_WALLET_ASSETS_INFO ) { const assetsInfo = await newUserClient.getUserAssets(); console.log("-AssetID--Asset--Balance--public_key--"); assetsInfo.forEach(function(element) { console.log(element.asset_id + " " + element.symbol + " " + element.balance + " " + element.public_key + " " + element.account_name + " " + element.account_tag ); }); // console.log(assetsInfo);}调用 getUserAssets API的完整输出如下: ...

May 16, 2019 · 3 min · jiezi

通过-Nodejs-买卖Bitcoin

上一章介绍了Exincore,你可以1秒完成资产的市价买卖。如果你想限定价格买卖,或者买卖一些exincore不支持的资产,你需要OceanOne。 方案二: 挂单Ocean.One交易所Ocean.one是基于Mixin Network的去中心化交易所,它性能一流。你可以在OceanOne上交易任何资产,只需要将你的币转给OceanOne, 将交易信息写在交易的memo里,OceanOne会在市场里列出你的交易需求,交易成功后,会将目标币转入到你的MixinNetwork帐上,它有三大特点与优势: 不需要在OceanOne注册不需要存币到交易所支持所有Mixin Network上能够转账的资产,所有的ERC20 EOS代币。预备知识:你先需要创建一个机器人, 方法在 教程一. 安装依赖包我们需要依赖 msgpack5 and mixin-node-client ,第四章 已经做过介绍, 你应该先安装过它了. 充币到 Mixin Network, 并读出它的余额.此处演示用 USDT购买BTC 或者 用BTC购买USDT。交易前,先检查一下钱包地址。完整的步骤如下: 检查比特币或USDT的余额,钱包地址。并记下钱包地址。从第三方交易所或者你的冷钱包中,将币充到上述钱包地址。再检查一下币的余额,看到帐与否。(比特币的到帐时间是5个区块的高度,约100分钟)。比特币与USDT的充值地址是一样的。 if ( args.type === TYPE_WALLET_ASSETS_INFO ) { const assetsInfo = await newUserClient.getUserAssets(); console.log("-AssetID--Asset--Balance--public_key--"); assetsInfo.forEach(function(element) { console.log(element.asset_id + " " + element.symbol + " " + element.balance + " " + element.public_key + " " + element.account_name + " " + element.account_tag ); }); // console.log(assetsInfo);}取得Ocean.one的市场价格信息如何来查询Ocean.one市场的价格信息呢?你要先了解你交易的基础币是什么,如果你想买比特币,卖出USDT,那么基础货币就是USDT;如果你想买USDT,卖出比特币,那么基础货币就是比特币. ...

May 15, 2019 · 4 min · jiezi

跟着我们学Golang之面向对象

万物皆对象。学过Java编程的都知道Java是一门面向对象的语言,它拥有封装、继承和多态的特性。那可不可以说,拥有封装、继承和多态这一特性的语言就是面向对象的语言呢?仔细想来,也确实是这样的,因为封装、继承和多态这三个特征,并不是Java语言的特征,而是面向对象的三大特征。总结来看,所有包含封装、继承和多态者三大特征的语言都可以说是面向对象的语言。 那么Go语言是否是一门面向对象的语言呢?下面我们通过举例的方式针对封装、继承和多态这面向对象的三大特征分别进行解释。 <!-- more --> 封装Go中有struct结构体,通过结构体能够实现现实世界中对象的封装。如将学生封装成对象,除了学生的基础信息外,还需要一些学生的基础行为。 定义结构体的方式之前在基础结构中进行了简单的解释,并没有针对结构体的方法进行说明。这里先说明一下定义结构体的方法。 func(alias type) func_name(parameter1 type, parameter2 type2)(ret1 type3, ret2 type4){ ...}定义结构体的方法的语法与函数的语法类似,区别于普通函数,方法的定义在func后有一个括号(alias type),指定方法的附属结构体,以方便通过结构体来进行方法的使用。 看到这里不免有些Java的同学觉得不太好接受,毕竟在Java中,对象的方法都是写在class中的,在Go中方法都是写在结构体外的。 所以可以总结一句,Go中的函数分为两类,一种是有附属于结构体的方法,一种是普通函数。附属于结构体的函数,在使用的过程中,需要结合结构体来使用,必须像Java那样先声明对象,然后结合对象才能使用。普通函数仅有是否可被外部包访问的要求,不需要先声明结构体,结合结构体来使用,开盖即食哈。 方法的结构体在指定时,alias别名可以随意设置,但是所属类型不能,(此处有坑)下面看一个例子 package mainimport "fmt"type Student struct { Name string Learned []string}func (s Student) learnEnglish() { s.Learned = append(s.Learned, "i'm fine, thank you")}func (s *Student) learnMath() { s.Learned = append(s.Learned, "1 + 1 = 2")}func (s *Student) whoAmI() { fmt.Println("your name is : ", s.Name)}func (s Student) whoAmII() { fmt.Println("your name is : ", s.Name)}func main() { s := Student{Name: "jack"} s.whoAmI() s.whoAmII() s.learnEnglish() //学英语 s.learnMath() //学数学 fmt.Println(s.Name, "学过: ") for _, learned := range s.Learned { fmt.Printf("\t %s \n", learned) }}/*运行结果:your name is : jackyour name is : jackjack 学过: 1 + 1 = 2---没有学过英语???*/append为Go自带函数,向数组和slice中添加元素这里有四个方法,两个打印名字的方法和两个学习的方法,区别点在于方法的所属类型一个是指针类型,另一个是非指针类型。 ...

May 13, 2019 · 6 min · jiezi

通过-Go-在去中心化交易所OceanOne上挂单买卖任意ERC20-token

在上一课中,我们介绍了如何在OceanOne交易比特币。OceanOne支持交易任何Mixin Network上的token,包括所有的ERC20和EOS token,不需要任何手续和费用,直接挂单即可。下面介绍如何将将一个ERC20 token挂上OceanOne交易!在掌握了ERC20 token之后,就可以把任何token在Ocean上买卖。 此处我们用一个叫做Benz的ERC20 token为例。这个token已经被充值进Mixin Network,你可以在区块链浏览器看到这个token在Mixin Network内部的总数和交易 预备知识:先将Ben币存入你的钱包,然后使用ReadAssets API读取它的UUID. 取得该币的UUID调用 ReadAssets API 会返回json数据, 如: asset_id 币的UUID.public_key 该币的当前钱包的地址.symbol 币的名称. 如: Benz.if cmd == "aw" { priKey, _, sID, userID, _ := GetWalletInfo() assets, err := mixin.ReadAssets(userID,sID,priKey) if err != nil { log.Fatal(err) } var AssetsInfo map[string]interface{} err = json.Unmarshal(assets, &AssetsInfo) if err != nil { log.Fatal(err) } // fmt.Println("Data is: ",AssetsInfo["data"].(map[string]interface{})["public_key"]) for _, v := range (AssetsInfo["data"].([]interface{})) { if v.(map[string]interface{})["symbol"] == "EOS" { fmt.Println(v.(map[string]interface{})["symbol"]," ", v.(map[string]interface{})["asset_id"]," ", v.(map[string]interface{})["account_name"]," ", v.(map[string]interface{})["account_tag"]," ", v.(map[string]interface{})["balance"]) } else { fmt.Println(v.(map[string]interface{})["symbol"]," ", v.(map[string]interface{})["asset_id"]," ", v.(map[string]interface{})["public_key"]," ", v.(map[string]interface{})["balance"]) } }}调用 ReadAssets API的完整输出如下: ...

May 13, 2019 · 3 min · jiezi

用C在去中心化交易所OceanOne上挂单买卖任意ERC20-token

用C#在去中心化交易所OceanOne上挂单买卖任意ERC20 token 在上一课中,我们介绍了如何在OceanOne交易比特币。OceanOne支持交易任何Mixin Network上的token,包括所有的ERC20和EOS token,不需要任何手续和费用,直接挂单即可。下面介绍如何将将一个ERC20 token挂上OceanOne交易。掌握了ERC20的代币买卖之后,你就可以用同样的方法买卖任何EOS以及其他Mixin Network上的token 此处我们用一个叫做Benz的ERC20 token为例。这个token已经被充值进Mixin Network,你可以在区块链浏览器看到这个token在Mixin Network内部的总数和交易 预备知识:先将Ben币存入你的钱包,然后使用getAssets API读取它的UUID. 取得该币的UUID调用 getAssets API 会返回json数据, 如: asset_id 币的UUID.public_key 该币的当前钱包的地址.symbol 币的名称. 如: Benz.if (cmd == "aw" ) { // Console.WriteLine(mixinApi.VerifyPIN(USRCONFIG.PinCode.ToString()).ToString()); MixinApi mixinApiNewUser = GetWalletSDK(); var assets = mixinApiNewUser.ReadAssets(); string wuuid = GetWalletUUID(); Console.WriteLine("Current wallet uuid is " + wuuid); foreach (Asset asset in assets) { if (asset.symbol == "EOS") { Console.WriteLine(asset.symbol + " Public Address is: " + asset.account_name + " " + asset.account_tag + " Balance is: " + asset.balance); } else Console.WriteLine(asset.symbol + " Public Address is: " + asset.public_key + " Balance is: " + asset.balance); Console.WriteLine(); }}调用 getAssets API的完整输出如下: ...

May 9, 2019 · 3 min · jiezi

PHP比特币开发教程在去中心化交易所OceanOne上挂单买卖比特币

上一章介绍了Exincore,你可以1秒完成资产的市价买卖。如果你想限定价格买卖,或者买卖一些exincore不支持的资产,你需要OceanOne。 方案二: 挂单Ocean.One交易所Ocean.one是基于Mixin Network的去中心化交易所,它性能一流。你可以在OceanOne上交易任何资产,只需要将你的币转给OceanOne, 将交易信息写在交易的memo里,OceanOne会在市场里列出你的交易需求,交易成功后,会将目标币转入到你的MixinNetwork帐上,它有三大特点与优势: 不需要在OceanOne注册不需要存币到交易所支持所有Mixin Network上能够转账的资产,所有的ERC20 EOS代币。预备知识:你先需要创建一个机器人, 方法在 教程一. 安装依赖包正如教程一里我们介绍过的, 我们需要依赖 mixin-sdk-php, 你应该已经先安装过它了. 安装依赖的库第四课, 在上一课中已经安装好了. 充币到 Mixin Network, 并读出它的余额.此处演示用 USDT购买BTC 或者 用BTC购买USDT。交易前,先检查一下钱包地址。完整的步骤如下: 检查比特币或USDT的余额,钱包地址。并记下钱包地址。从第三方交易所或者你的冷钱包中,将币充到上述钱包地址。再检查一下币的余额,看到帐与否。(比特币的到帐时间是5个区块的高度,约100分钟)。比特币与USDT的充值地址是一样的。 const BTC_ASSET_ID = "c6d0c728-2624-429b-8e0d-d9d19b6592fa"; const EOS_ASSET_ID = "6cfe566e-4aad-470b-8c9a-2fd35b49c68d"; const USDT_ASSET_ID = "815b0b1a-2764-3736-8faa-42d694fa620a"; $mixinSdk_eachAccountInstance = new MixinSDK(GenerateConfigByCSV($data)); $asset_info = $mixinSdk_eachAccountInstance->Wallet()->readAsset(BTC_ASSET_ID); print_r("Bitcoin wallet address is :".$asset_info["public_key"]."\n"); print_r("Bitcoin wallet balance is :".$asset_info["balance"]."\n");取得Ocean.one的市场价格信息如何来查询Ocean.one市场的价格信息呢?你要先了解你交易的基础币是什么,如果你想买比特币,卖出USDT,那么基础货币就是USDT;如果你想买USDT,卖出比特币,那么基础货币就是比特币. if ( $ocmd == '1') { getOceanOneMarketInfos(XIN_ASSET_ID,USDT_ASSET_ID);}function getOceanOneMarketInfos($targetCoin, $baseCoin) { $client = new GuzzleHttp\Client(); $baseUrl = "https://events.ocean.one/markets/".$targetCoin."-".$baseCoin."/book"; $res = $client->request('GET', $baseUrl, [ ]); if ($res->getStatusCode() == "200") { // echo $res->getStatusCode() . PHP_EOL; $resInfo = json_decode($res->getBody(), true); echo "Side | Price | Amount | Funds" . PHP_EOL; foreach ($resInfo["data"]["data"]["asks"] as $key => $exchange) { echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; } foreach ($resInfo["data"]["data"]["bids"] as $key => $exchange) { echo $exchange["side"] . " " . $exchange["price"] . " " . $exchange["amount"] ." " . $exchange["funds"] . PHP_EOL; } }}交易前,创建一个Memo!在第二章里,基于Mixin Network的 PHP 比特币开发教程: 机器人接受比特币并立即退还用户, 我们学习过转帐,这儿我们介绍如何告诉Ocean.one,我们给它转帐的目的是什么,信息全部放在memo里. ...

April 30, 2019 · 3 min · jiezi

Java-比特币开发系列教程汇总

创建一个机器人机器人接受比特币并立即退还用户创建比特币钱包市场价闪兑比特币在去中心化交易所限价买卖比特币在去中心化交易所自由挂单买卖任意ERC20 token其他编程语言比特币开发教程如下: Python 比特币开发教程Go 比特币开发教程Java 比特币开发教程Node.js 比特币开发教程C# 比特币开发教程PHP 比特币开发教程Mixin Network 开发者资源汇总

April 28, 2019 · 1 min · jiezi

(第一讲)Spring Initializr-快速入门Spring Boot的最好选择

Spring Initializr [http://start.spring.io/]是引导你快速构建Spring Boot项目的不二选择。 它允许你通过简单的操作步骤,就可以构建出一个完整的Spring Boot应用程序。你可以通过Spring Initializr引导界面构建如下类型的Spring Boot应用: Web应用程序Restful 应用程序Batch应用程序Spring Boot对很多第三方框架提供了良好的支持,可以通过对应的artifactId获得他们,这里列举其中的一部分供参考: spring-boot-starter-web-services:用于构建可与外界交互的SOAP Web服务应用程序spring-boot-starter-web:可用于构建Web应用程序或者基于Restful风格的应用程序spring-boot-starter-test:可用于构建并编写单元测试和集成测试spring-boot-starter-jdbc:构建基于JDBC的应用程序spring-boot-starter-hateoas:通过引入HATEOAS功能,让你轻松实现RESTful服务spring-boot-starter-security:使用Spring Security对系统用户进行身份验证和鉴权spring-boot-starter-data-jpa:基于Hibernate实现的Spring Data JPAspring-boot-starter-cache:开启基于Spring Framework的缓存支持spring-boot-starter-data-rest:使用Spring Data REST提供REST服务在本讲中,我将通过使用Spring Initializr来演示如何快速创建一个简单的Web应用程序。 使用Spring Initializr构建Web应用程序使用Spring Initializr构建Web应用程序是一件非常简单快速的事情。 如上图所示,我们需要执行如下的几个操作: 通过浏览器访问Spring Initializr官网 ,然后再执行下面的几个选择项 设置groupId : com.ramostear.spring.boot设置artifactId: spring-boot-quick-start项目名称:默认为spring-boot-quick-start基础包名:默认即可(你也可以选择修改)(通过点击More options展开)在搜索框中分别检索并选择如下几个组件:Web,Actuator,DevTools最后,点击“Generate Project”生成并下载项目将项目导入到IntelleJ IDEA中Spring Boot项目目录结构下图显示了在IDEA中导入刚才下载的项目目录结构: SpringBootQuickStartApplication.java:Spring Boot运行的主文件,它负责初始化Spring Boot自动配置和Spring应用程序上下文application.properties : 应用程序配置文件SpringBootQuickStartApplicationTests : 用于单元测试的简单启动器pom.xml : Maven构建项目的配置文件,包括了Spring Boot Starter Web等相关依赖项。特别指出,它会自动将Spring Boot Starter Parent作为整个工程的父依赖。核心的代码src/main/java 包下放置我们主要的逻辑代码,src/test/java包下放置项目的测试代码,src/main/resources包下放置项目的配置文件以及一些静态资源文件,如页html文件,css文件和js文件等。我们从上到下依次进行介绍。 SpringBootQuickStartApplication.javapackage com.ramostear.spring.boot.springbootquickstart;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class SpringBootQuickStartApplication { public static void main(String[] args) { SpringApplication.run(SpringBootQuickStartApplication.class, args); }}@SpringBootApplication : 负责初始化Spring Boot 自动化配置项和Spring应用程序上下文SpringApplication.run() : 负责启动Spring Boot应用程序的静态方法application.propertiesSpring Boot应用程序的配置文件,这里我们简单的设置一下项目启动的端口为8080(默认端口8080)和应用名称为Spring Boot Quick Start: ...

April 21, 2019 · 2 min · jiezi

对话巨杉核心研发团队:分布式数据库自研之路

一直以来,数据库的核心研发团队都十分神秘,作为隐藏在幕后的隐士高人,他们对数据库发展以及数据库研发团队的看法是什么呢?本文我们就由巨杉数据库核心技术研发团队的“老司机”,向大家分享他分布式数据库的自研之路。Q:作为数据库行业的“老司机”,您能否先介绍一下自己?A:我叫Danny,是巨杉数据库核心研发团队的成员,是一名数据库资深工程师和架构师,有超过20年的数据库核心研发经验,曾经作为DB2 内核研发团队成员参与了DB2 ,DPF等产品的架构设计和研发工作。目前,我们北美研发实验室的团队已经有很多数据库的专家“老司机”加入,全部来自DB2 的核心技术团队。虽然我们团队很多都是来自IBM、华为的“传统企业级IT人”,不太喜欢抛头露面。但是现在是技术圈一个变革的新时代,我们的产品已经开源了,所以我们之后也会让我们团队的技术大牛们多多参与社区活动,分享一下我们做数据库核心研发的心得,同时也和大家一起进步。Q:作为“老IBM”,您认为像IBM这样历史悠久的IT企业,他们的核心研发团队是怎么样的呢?您对此感受最深的是什么?A:IBM是最早提出“关系型数据库”这一概念和理论体系的公司,从技术上看,传统三大关系型数据库在发展过程中,其实已经具有很深远的技术储备了。DB2是三大传统关系型数据库中唯一的分布式产品,因此我们团队在分布式技术方面的积累是一脉相承的。我在DB2的十几年里,感受最深的就是技术底蕴和沉淀。比如说,在Unix真正支持线程机制之前,针对多线程模型,甚至是针对不同的硬件设备,他们早已使用汇编语言实现了逻辑线程的切换和调用,这些机制在当时其实是相当领先的。说到研发团队,IBM的实验室也是卧虎藏龙。从最初使用汇编语言开始的技术专家们,一直在参与数据库、操作系统和编译器底层的研发工作,可以说正是他们创造了最早的关系型数据库的概念,也是他们真正把数据库打造成为一个通用的软件平台。Q:像数据库这样的基础软件,技术上的难度是什么?A:数据库软件,特别是一款真正企业级ready的产品,并没有大家想象的,只是开发一款软件那么简单。从技术上来说,数据库既需要有技术基因的传承,又需要创新。数据库技术到现在已经发展了40多年了。在技术的发展中,数据库软件/平台已经成为一个功能复杂,架构庞大,安全要求很高的庞大软件产品体系。因此,技术上既需要技术的积累,也需要新的创新。同时,在应用端这边,由于用户都是银行、政府等这些30年前就开始使用数据库的老客户,他们通常无法承担全盘迁移的风险,因此在业务技术架构上,难免保留了各个时代的历史遗留,比如说,北美一些银行的核心IT系统,直到目前仍然运行在40年前的技术平台之上。这也要求企业级ready的数据库基础软件需要有很强的兼容能力,不但可以保证旧业务的运行,还可以不断地推陈出新。这种创新是必须的,但在技术上却又是最难的。Q:以您近20年的数据库行业经验,您认为数据库核心团队应该是怎么样的?A:我认为数据库核心研发团队的基因很重要,就比如说IBM的DB2团队,就是以多位数据库领域的“老炮儿”为核心,搭配有技术实力的资深工程师,而不像现在很多的开源新产品,他们都是以年轻的创新团队为主。就像我上面提到的技术复杂度和产品历史跨度的问题,数据库产品如果要在大型企业内使用,技术团队必须要有传统数据库的开发经验,这也就是技术老炮儿存在的作用。简单说,数据库基础软件就是创新技术和技术经验积累的融合体。Q:海内外基础软件研发有什么不同?A:相对来说,海外拥有技术人才的基础,也有像IBM Oracle这样的体系的沿袭,培养出了一批批技术人才和团队。所以现在北美很多新一代基础软件产品团队其实还是围绕了老一辈的“老司机”构建的。国内基础软件的人才积累还不够,因此基础软件领域还没有完全形成基础软件领域的武林门派,这也是近年来基础软件和AI领域国内企业疯狂往外招人的原因。但是数据库由于历史原因,国内无论是互联网还是科研团队想要形成独特的门派,还需要时间。巨杉这边我们的团队拥有以王涛为代表的很多DB2 团队的核心技术专家,以及来自华为的技术核心团队成员,是技术基因和技术创新很好的结合。Q:数据库开发和其他软件有什么不同?A:因为刚才提到的这些特点,基础软件特别是数据库的研发,和其他应用软件有很大的不同。其中最大的一个不同点就是开发语言和开发模式。从计算机的发展来看,C是最面向机器语言(汇编代码)的,原则上每一行C代码都可以很精准地映射到一些汇编指令上,因此从对操作系统底层的操控来看最为精准。C++则是在C之上发展起来的面向对象语言。在底层编程中,C++的高级特性被使用的非常少,但是其设计模式对于模块化开发很有帮助。因此使用C++既可以兼顾对操作系统底层最精准的把控,也可以将一些面向对象的理念融入代码中,在复杂系统构建时起到重要作用。如今新的一些新型开发语言则不是面向对象,因此在设计模式上不适合大型复杂系统的开发。同时,这些语言语言简化了很多C/C++里最为重要的指针概念,使其对内存的精准操作变得不可能完成。指针这个概念用好了是神器,用差了是垃圾,大部分能力不高的程序员,或者没有非常完善测试框架的项目很难完美把握指针这类高级特性,使得大型项目开发里面内存泄露和崩溃漏洞遍地都是。但是对于我们巨杉来说,有着DB2数据库内核的研发经验,从人员能力,到代码质量管理,到测试框架的完善都能够完美驾驭这类高级特性,最大程度挖掘出操作系统和数据库底层的性能与处理能力。Q:分布式数据库方向是什么?A:根据Gartner和我们CTO王涛的共同观点,真正特别大使得传统关系型数据库存不下的表相对来讲数量都是可控的。因此有很多workaround都可以搞定这个问题,这也是为什么传统以来大家用分库分表虽然麻烦,但也不是解决不了应用问题。数据库其实真正面临的痛点是“微服务”下,数据服务的资源池化。应用程序从传统烟囱式构建,向微服务转型的过程中,在每一个微服务上都放一个独立的数据库已经是不可能的事情了。这种情况下,数据服务资源池需要直接面向上层成百上千个,来自不同开发商、不同团队的,开发能力不一、应用类型不同、SLA安全级别不同等等的各类需求。因此,资源池必须拥有弹性扩张、资源隔离、多租户、可配置一致性、多模式(支持各类SQL协议)、集群内可配置容灾策略等一系列功能,同时每个数据库实例的计算和存储能力需要做到能够无限扩张,毕竟有些微服务可能会涉及到极多的流水数据,不能限定每个数据库实例使用的资源仅局限于一台物理设备。所以说,单纯为了分布式的OLTP只是解决了不构成刚需的问题(分库分表早可以解决),但是在微服务应用开发的环境下,数据库更是要从资源池化的角度对上层提供服务,同时资源池中的每个数据库实例内部也要支持分布式交易等一系列特性,做到与传统数据库的全兼容。Q:SequoiaDB自从发布3.0版本以来,在社区和市场得到的反馈都很好,能否透露一下产品的一些新动向?A:近期,我们会发布一个新的版本,其中OLTP场景选性能会有大的提升,同时对于SQL处理能力也会有很大提升。在分布式的交易型业务下,整体性能提升将比现在版本有23倍的提升,对比同类产品性能将高出56倍以上。这些在本周的活动我们也会做一个简单的分享和介绍。3月30号,本周末我们巨杉Techday的第二期活动也会在北京举办,我们也会带来一些深度的技术分享,届时也会有现场的视频直播,希望大家也能多多关注和参与!未来我们也会有更多“神秘”的数据库“老司机”给大家带来技术、趋势、见闻的分享~

March 28, 2019 · 1 min · jiezi

Vue.js-组件详解

学习笔记:组件详解组件详解组件与复用Vue组件需要注册后才可以使用。注册有全局注册和局部注册两种方式。全局注册Vue.component(‘my-component’, {});要在父实例中使用这个组件,必须要在实例创建前注册,之后就可以用<my-component></my-component>的形式来使用组件。Vue.component(‘my-component’, { template: &lt;div&gt;这是一个组件&lt;/div&gt;});template的DOM结构必须被一个元素包含,缺少<div></div>会无法渲染并报错。在Vue实例中,使用components选项可以局部注册组件,注册后的组件只在该实例作用域下有效。组件中也可以使用components选项来注册组件,使组件可以嵌套。var Child = { template: &lt;div&gt;局部注册组件的内容&lt;/div&gt;};new Vue({ el: ‘#app’, components: { ‘my-component’: Child },});Vue组件的模板在某些情况下会受到HTML的限制,比如<table>内规定只允许是<tr>、<td>、<th>等这些表格元素,所以在<table>内直接使用组件时无效的。这种情况下,可以使用特殊的is属性来挂载组件。<div id=“app”> <table> <tbody is=“my-component”></tbody> </table></div>Vue.component(‘my-component’, { template: &lt;div&gt;这里是组件内容&lt;/div&gt;});常见的限制元素还有<ul>、<ol>、<select>。除了template选项外,组件中还可以像Vue实例那样使用其他的选项,比如data、computed、methods等。但是在使用data时,data必须是函数,然后将数据return出去。JavaScript对象是引用关系,如果return的对象引用了外部的一个对象,那这个对象就是共享的,任何一方修改都会同步。使用props传递数据组件不仅要把模板的内容进行复用,更重要的是组件间进行通信。通常父组件的模板中包含子组件,父组件要正向地向子组件传递数据或参数,子组件接收后根据参数的不同渲染不同的内容或者执行操作。这个正向传递数据的过程通过props来实现。在组件中,使用选项props声明需要从父级接收的数据,props的值可以是两种,一种是字符串数组,一种是对象。<my-component message=“来自父组件的数据”></my-component>props: [‘message’],template: &lt;div&gt;{{message}}&lt;/div&gt;,props中声明的数据与组件data函数中return的数据主要区别就是props的数据来自父级,而data中的是组件自己的数据,作用域是组件本身,这两种数据都可以在模板template及计算属性computed和方法methods中使用。由于HTML特性不区分大小写,当使用DOM模板时,驼峰命名的props名称要转为短横线分割命名。<my-component warning-text=“提示信息”></my-component>有时候,传递的数据并不是直接写死,而是来自父级的动态数据,这时可以使用指令v-bind动态绑定props的值,当父组件的数据变化时,也会传递子组件。<div id=“app”> <input type=“text” v-model=“parentMessage”> <my-component :message=“parentMessage”></my-component></div>props: [‘message’],template: &lt;div&gt;{{message}}&lt;/div&gt;,data: { parentMessage: ‘’}这里用v-model绑定了父级的数据parentMessage,当通过输入框任意输入时,子组件接收到的props[“message”]也会实时响应,并更新组件模板。单向数据流业务中会经常遇到两种需要改变prop的情况,一种是父组件传递初始值进来,子组件将它作为初始值保存起来,在自己的作用域下可以随意使用和修改。这种情况可以在组件data内再声明一个数据,引用父组件的prop。<div id=“app”> <my-component :init-count=“1”></my-component></div>Vue.component(‘my-component’, { props: [‘initCount’], template: &lt;div&gt;{{count}}&lt;/div&gt;, data() { return { count:this.initCount } }});组件中声明了数据count,它在组件初始化时会获取来自父组件的initCount,之后就与之无关了,只用维护count,这样就可以避免直接操作initCount。另一种情况就是prop作为需要被转变的原始值传入,这种情况用计算属性就可以。<div id=“app”> <my-component :width=“100”></my-component></div>Vue.component(‘my-component’, { props: [‘width’], template: &lt;div :style="style"&gt;组件内容&lt;/div&gt;, computed: { style: function () { return { width: this.width + ‘px’ } } }});因为用CSS传递宽度要带单位(px),数值计算一般不带单位,所以统一在组件内使用计算属性。在JavaScript中对象和数组时引用类型,指向同一个内存空间,所以props是对象和数组时,在子组件内改变是会影响父组件。数组验证当prop需要验证时,需要对象写法。一般当组件需要提供给别人使用时,推荐都进行数据验证。比如某个数据必须是数字类型,如果传入字符串,就会在控制台弹出警告。<p data-height=“565” data-theme-id=“0” data-slug-hash=“WywyjV” data-default-tab=“js” data-user=“whjin” data-embed-version=“2” data-pen-title=“prop” class=“codepen”>See the Pen prop by whjin (@whjin) on CodePen.</p><script async src=“https://static.codepen.io/ass...;></script>验证的type类型可以是:StringNumberBooleanObjectArrayFunctiontype也可以是一个自定义构造器,使用instanceof检测。组件通信组件关系可分为父组件通信、兄弟组件通信、跨级组件通信。自定义事件当子组件需要向父组件传递数据时,就要用到自定义事件。v-on除了监听DOM事件外,还可以用于组件之间的自定义事件。JavaScript的设计模式——观察者模式方法:dispatchEventaddEventListenerVue组件的子组件用$emit()来触发事件,父组件用$on()来监听子组件的事件。父组件也可以直接在子组件的自定义标签上使用v-on来监听子组件触发的自定义事件。<p data-height=“365” data-theme-id=“0” data-slug-hash=“ZRWjKv” data-default-tab=“js,result” data-user=“whjin” data-embed-version=“2” data-pen-title=“自定义事件” class=“codepen”>See the Pen 自定义事件 by whjin (@whjin) on CodePen.</p><script async src=“https://static.codepen.io/ass...;></script>在改变组件的data “counter"后,通过$emit()再把它传递给父组件,父组件用@increase和@reduce。$emit()方法的第一个参数是自定义事件的名称。除了用v-on在组件上监听自定义事件外,也可以监听DOM事件,这时可以用.native修饰符表示监听时一个原生事件,监听的是该组件的根元素。<my-component @click:native=“handleClick”></my-component>使用v-modelVue可以在自定义组件上使用v-model指令。<my-component v-model=“total”></my-component>组件$emit()的事件名时特殊的input,在使用组件的父级,并没有在<my-component>上使用@input=“handler”,而是直接用了v-model绑定的一个数据total。<my-component @input=“handleGetTotal”></my-component>v-model还可以用来创建自定义的表单输入组件,进行数据双向绑定。<p data-height=“365” data-theme-id=“0” data-slug-hash=“zaqJBQ” data-default-tab=“html,result” data-user=“whjin” data-embed-version=“2” data-pen-title=“v-model双向绑定” class=“codepen”>See the Pen v-model双向绑定 by whjin (@whjin) on CodePen.</p><script async src=“https://static.codepen.io/ass...;></script>实现这样一个具有双向绑定的v-model组件要满足下面两个要求:接收一个value属性在有新的value时触发input事件非父子组件通信在实际业务中,除了父子组件通信外,还有很多非父子组件通信的场景,非父子组件一般有两种,兄弟组件和跨多级组件。在Vue 1.x版本中,除了$emit()方法外,还提供了¥dispatch()和$broadcast()。$dispatch()用于向上级派发事件,只要是它的父级(一级或多级以上),都可以在Vue实例的events选项内接收。此实例只在Vue 1.x版本中有效:<p data-height=“365” data-theme-id=“0” data-slug-hash=“pKyOOY” data-default-tab=“html,result” data-user=“whjin” data-embed-version=“2” data-pen-title=“dispatch派发事件” class=“codepen”>See the Pen dispatch派发事件 by whjin (@whjin) on CodePen.</p><script async src=“https://static.codepen.io/ass...;></script>$broadcast()是由上级向下级广播事件,用法完全一致,方向相反。这两种方法一旦发出事件后,任何组件都可以接收到,就近原则,而且会在第一次接收到后停止冒泡,除非返回true。这些方法在Vue 2.x版本中已废弃。在Vue 2.x中,推荐任何一个空的Vue实例作为中央事件总线(bus),也就是一个中介。<p data-height=“365” data-theme-id=“0” data-slug-hash=“dKMgvJ” data-default-tab=“html,result” data-user=“whjin” data-embed-version=“2” data-pen-title=“Vue-bus事件总线” class=“codepen”>See the Pen Vue-bus事件总线 by whjin (@whjin) on CodePen.</p><script async src=“https://static.codepen.io/ass...;></script>首先创建了一个名为bus的空的Vue实例;然后全局定义了组件component-a;最后创建了Vue实例app。在app初始化时,也就是在生命周期mounted钩子函数里监听了来自bus的事件on-message,而在组件component-a中,点击按钮后会通过bus把事件on-message发出去。此时app就会接收到来自bus的事件,进而在回调里完成自己的业务逻辑。这种方法巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。如果深入使用,可以扩展bus实例,给它添加data、methods、computed等选项,这些都是可以公用的。在业务中,尤其是协同开发时非常有用,因为经常需要共享一些通用的信息,比如用户登录的昵称、性别、邮箱等,还有用户的授权token等。只需在初始化时让bus获取一次,任何时间、任何组件就可以从中直接使用,在单页面富应用(SPA)中会很实用。除了中央事件总线bus外,还有两种方法可以实现组件间通信:父链和子组件索引。父链在子组件中,使用this.$parent可以直接访问该组件的父实例或组件,父组件也可以通过this.$children访问它所有的子组件,而且可以递归向上或向下无限访问,直到根实例或最内层的组件。<div id=“app”> <p>{{message}}</p> <component-a></component-a></div>Vue.component(‘component-a’, { template: &lt;button @click="handleEvent"&gt;通过父链直接修改数据&lt;/button&gt;, methods: { handleEvent: function () { this.$parent.message = ‘来自组件component-a的内容’ } }});var app = new Vue({ el: ‘#app’, data: { message: ’’ }});尽管Vue允许这样操作,但在业务中,子组件应该尽可能地避免依赖父组件的数据,更不应该去主动修改它的数据,因为这样使得父子组件紧耦合,只看父组件,很难理解父组件的状态,因为它可能被任意组件修改,理想状态下,只有组件自己能修改它的状态。父子组件最好还是通过props和$emit()来通信。子组件索引当子组件较多时,通过this.$children来遍历出需要的一个组件实例是比较困难的,尤其是组件动态渲染时,它们的序列是不固定的。Vue提供了子组件索引的方法,用特殊的属性ref来为子组件指定一个索引名称。<p data-height=“365” data-theme-id=“0” data-slug-hash=“dKMLXY” data-default-tab=“html,result” data-user=“whjin” data-embed-version=“2” data-pen-title=“Vue-$refs” class=“codepen”>See the Pen <a href=“https://codepen.io/whjin/pen/dKMLXY/">Vue-$refs</a> by whjin (@whjin) on CodePen.</p><script async src=“https://static.codepen.io/ass...;></script>在父组件模板中,子组件标签上使用ref指定一个名称,并在父组件内通过this.$refs来访问指定名称的子组件。$refs只在组件渲染完成后才填充,并且它是非响应式的。它仅仅作为一个直接访问子组件的应急方案,应当避免在模板或计算属性中使用$refs。Vue 2.x将v-el和v-ref合并成ref,Vue会自动去判断是普通标签还是组件。使用slot分发内容当需要让组件组合使用,混合父组件的内容与子组件的模板时,就会用到slot,这个过程叫做内容分发。<app>组件不知道它的挂载点会有什么内容。挂载点的内容是由<app>的父组件决定的。<app>组件很可能有它自己的模板。props传递数据、events触发事件和slot内容分发就构成了Vue组件的3个API来源,再复杂的组件也是由这3部分构成。作用域父组件中的模板:<child-component> {{message}}</child-component>这里的message就是一个slot,但是它绑定的是父组件的数据,而不是组件<child-component>的数据。父组件模板的内容是在父组件作用域内编译,子组件模板的内容是在子组件作用域内编译。<div id=“app”> <child-component v-modle=“showChild”></child-component></div>Vue.component(‘child-component’, { template: &lt;div&gt;子组件1&lt;/div&gt;,});var app = new Vue({ el: ‘#app’, data: { showChild: true }});这里的状态showChild绑定的是父组件的数据。在子组件上绑定数据:<div id=“app”> <child-component></child-component></div>Vue.component(‘child-component’, { template: &lt;div v-model="showChild"&gt;子组件&lt;/div&gt;, data() { return { showChild: true } }});var app = new Vue({ el: ‘#app’,});因此,slot分发的内容,作用域是在父组件上。单个slot在子组件内使用特殊的<slot>元素就可以为这个组件开启一个slot(插槽),在父组件模板里,插入在子组件标签内的所有内容将替代子组件的<slot>标签及它的内容。<div id=“app”> <child-component> <p>分发的内容</p> <p>更多分发的内容</p> </child-component></div>Vue.component(‘child-component’, { template: &lt;div&gt; &lt;slot&gt; &lt;p&gt;如果没有父组件插入内容,我将作为默认出现。&lt;/p&gt; &lt;/slot&gt; &lt;/div&gt; ,});var app = new Vue({ el: ‘#app’,});子组件child-component的模板内定义了一个<slot>元素,并且用一个<p>作为默认的内容,在父组件没有使用slot时,会渲染这段默认的文本;如果写入了slot,就会替换整个<slot>。子组件<slot>内的备用内容,它的作用域是子组件本身。具名Slot给<slot>元素指定一个name后可以分发多个内容,具名slot可以与单个slot共存。<p data-height=“265” data-theme-id=“0” data-slug-hash=“RJRVQJ” data-default-tab=“html,result” data-user=“whjin” data-embed-version=“2” data-pen-title=“Vue-slot” class=“codepen”>See the Pen Vue-slot by whjin (@whjin) on CodePen.</p><script async src=“https://static.codepen.io/ass...;></script>子组件内声明了3个<slot>元素,其中在<div class=“main”>内的<slot>没有使用name特性,它将作为默认slot出现,父组件没有使用slot特性的元素与内容都将出现在这里。如果没有指定默认的匿名slot,父组件内多余的内容都将被抛弃。在组合使用组件时,内容分发API至关重要。作用域插槽作用域插槽是一种特殊的slot,使用一个可以复用的模板替换已渲染元素。<div id=“app”> <child-component> <template scope=“props”> <p>来自父组件的内容</p> <p>{{props.msg}}</p> </template> </child-component></div>Vue.component(‘child-component’, { template: &lt;div class="container"&gt; &lt;slot msg="来自子组件的内容"&gt;&lt;/slot&gt;&lt;/div&gt; ,});var app = new Vue({ el: ‘#app’,});子组件的模板,在<slot>元素上有一个类似props传递数据给组件的写法msg=“xxx”,将数据传递到插槽。父组件中使用了<template>元素,而且拥有一个scope=“props"的特性,这里的props是一个临时变量。template内可以通过临时变量props访问来自子组件插槽的数据msg。作用域插槽更具代表性的用例是列表组件,允许组件自定义应该如何渲染列表每一项。<div id=“app”> <my-list :book=“books”> <!–作用域插槽也可以是具名的Slot–> <template slot=“book” scope=“props”> <li>{{props.bookName}}</li> </template> </my-list></div>Vue.component(‘my-list’, { props: { books: { type: Array, default: function () { return []; } } }, template: &lt;ul&gt; &lt;slot name="book" v-for="book in books" :book-name="book.name"&gt;&lt;/slot&gt;&lt;/ul&gt; ,});子组件my-list接收一个来自父级的prop数组books,并且将它在name为book的slot上使用v-for指令循环,同时暴露一个变量bookName。作用域插槽的使用场景是既可以复用子组件的slot,又可以使slot内容不一致。访问slotVue 2.x提供了用来访问被slot分发的内容的方法$slots。<p data-height=“365” data-theme-id=“0” data-slug-hash=“vrKZew” data-default-tab=“html,result” data-user=“whjin” data-embed-version=“2” data-pen-title=“Vue-$slots” class=“codepen”>See the Pen <a href=“https://codepen.io/whjin/pen/vrKZew/">Vue-$slots</a> by whjin (@whjin) on CodePen.</p><script async src=“https://static.codepen.io/ass...;></script>通过$slots可以访问某个具名slot,this.$slots.default包括了所有没有被包含在具名slot中的节点。组件高级用法递归组件给组件设置name选项,组件在它的模板内可以递归地调用自己。<div id=“app”> <child-component :count=“1”></child-component></div>Vue.component(‘child-component’, { name: ‘child-component’, props: { count: { type: Number, default: 1 } }, template: &lt;div class="child"&gt; &lt;child-component :count="count+1" v-if="count&lt;3"&gt;&lt;/child-component&gt;&lt;/div&gt; ,});组件递归使用可以用来开发一些具有未知层级关机的独立组件,比如级联选择器和树形控件等。内联模板组件的模板一般都是在template选项内定义的,Vue提供了一个内联模板的功能,在使用组件时,给组件标签使用inline-template特性,组件就会把它的内容当做模板,而不是把它当内容分发,这让模板更灵活。<p data-height=“265” data-theme-id=“0” data-slug-hash=“OEXjLb” data-default-tab=“html,result” data-user=“whjin” data-embed-version=“2” data-pen-title=“Vue-inline-template” class=“codepen”>See the Pen Vue-inline-template by whjin (@whjin) on CodePen.</p><script async src=“https://static.codepen.io/ass...;></script>在父组件中声明的数据message和子组件中声明的数据msg,两个都可以渲染(如果同名,优先使用子组件的数据)。这是内联模板的缺点,就是作用域比较难理解,如果不是非常特殊的场景,建议不要轻易使用内联模板。动态组件Vue.js提供了一个特殊的元素<component>用来动态地挂载不同的组件,使用is特性来选择要挂载的组件。<p data-height=“365” data-theme-id=“0” data-slug-hash=“zaBdyY” data-default-tab=“html,result” data-user=“whjin” data-embed-version=“2” data-pen-title=“Vue-component” class=“codepen”>See the Pen Vue-component by whjin (@whjin) on CodePen.</p><script async src=“https://static.codepen.io/ass...;></script>可以直接绑定在组件对象上:<div id=“app”> <component :is=“currentView”></component></div>var Home = { template: &lt;p&gt;Welcome home!&lt;/p&gt;};var app = new Vue({ el: ‘#app’, data: { currentView: Home }});异步组件Vue.js允许将组件定义为一个工厂函数,动态地解析组件。Vue.js只在组件需要渲染时触发工厂函数,并且把结果缓存起来,用于后面的再次渲染。<div id=“app”> <child-component></child-component></div>Vue.component(‘child-component’, function (resolve, reject) { window.setTimeout(function () { resolve({ template: &lt;div&gt;我是异步渲染的!&lt;/div&gt; }) }, 1000)});var app = new Vue({ el: ‘#app’,});工厂函数接收一个resolve回调,在收到从服务器下载的组件定义时调用。也可以调用reject(reason)指示加载失败。其他$nextTick异步更新队列Vue在观察到数据变化时并不是直接更新DOM,而是开启一个队列,并缓冲在同一个事件循环中发生的所有数据变化。在缓冲时会去除重复数据,从而避免不必要的计算和DOM操作。然后,在一下个事件循环tick中,Vue刷新队列并执行实际(已去重的)工作。Vue会根据当前浏览器环境优先使用原生的Promise.then和MutationObserver,如果都不支持,就会采用setTimeout代替。$nextTick就是用来确定什么时候DOM更新已经完成。<p data-height=“365” data-theme-id=“0” data-slug-hash=“RJRjgm” data-default-tab=“html,result” data-user=“whjin” data-embed-version=“2” data-pen-title=“Vue-$nextTick” class=“codepen”>See the Pen <a href=“https://codepen.io/whjin/pen/RJRjgm/">Vue-$nextTick</a> by whjin (@whjin) on CodePen.</p><script async src=“https://static.codepen.io/ass...;></script>X-TemplatesVue提供了另一种定义模板的方式,在<script>标签中使用text/x-template类型,并且指定一个id,将这个id赋给template。<div id=“app”> <my-component></my-component> <script type=“text/x-template” id=“my-component”> <div>这是组件的内容</div> </script></div>Vue.component(‘my-component’, { template: #my-component,});var app = new Vue({ el: ‘#app’,});手动挂载实例在一些非常特殊的情况下,需要动态地创建Vue实例,Vue提供了Vue.extend和$mount两个方法来手动挂载一个实例。Vue.extend是基础Vue构造器,创建一个“子类”,参数是一个包含组件选项的对象。如果Vue实例在实例化时没有收到el选项,它就处于“未挂载”状态,没有关联的DOM元素。可以使用$mount手动地挂载一个未挂载的实例。这个方法返回实例自身,因而可以链式调用其他实例方法。<p data-height=“265” data-theme-id=“0” data-slug-hash=“BVzmbL” data-default-tab=“html,result” data-user=“whjin” data-embed-version=“2” data-pen-title=“Vue-$mount” class=“codepen”>See the Pen <a href=“https://codepen.io/whjin/pen/BVzmbL/">Vue-$mount</a> by whjin (@whjin) on CodePen.</p><script async src=“https://static.codepen.io/ass...;></script>除了以上写法外,还有两种写法:new MyComponent().$mount("#app”);new MyComponent({ el: ‘#app’})手动挂载实例(组件)是一种比较极端的高级用法,在业务中几乎用不到,只在开发一些复杂的独立组件时可能会使用。 ...

March 18, 2019 · 3 min · jiezi

教你利用Windows访问控制搞事情

开篇福利FkUpdateWin10自动更新是真的烦人,每次按照网上的步骤禁用自动更新后,不用过多久系统又自动恢复了Update!于是自己研究了访问控制,利用访问控制原理修改服务对应的注册表权限,让系统无法修改服务的状态,达到永久禁用自动更新的效果!目前为止尚未发现Bug,所以共享给大家使用!只希望大家给文章点点赞!永久禁用Windows自动更新 - 下载连接FileLocker利用访问控制原理修改文件和上层目录的权限,使得文件不可被删除。目前为止也只能防止文件误删!之后可能会添加防止移动、防止修改等功能!防止文件误删 - 下载链接概念普及常用术语ACL(Access Control List) - Windows访问控制列表DACL(Discretionary Access Control List) - 任意访问控制列表SACL(System Access Control List) - 系统访问控制列表ACE(Access Control Entries) - 访问控制条目SD(Security Descriptor) - 安全描述符SID(Security Identifier) - 安全标识符AccessToken - 访问令牌详细解释从简单到复杂的依次解释SID,用于标识用户,组和计算机帐户,首次创建帐户时会获得一个唯一的SID用于标识该账户。简单来说就如同每个大学生入学都会分配一个唯一的学号,这个学号就是你的证明ACL,用来说明某个对象的访问权限,由DACL和SACL组成,具体的某项权限称为ACE。简单来说就如同大学校园里的各项规定,任何一个对象都有它特定的规则,假设某个具体对象为教室里的电脑,学生们只能看,而老师们可以操控,这就是教室里的电脑这个对象的访问权限SD,包含与安全对象相关的一些安全信息,包括该对象的所有者和所属组的SID,DACL,SACL以及一组控制位(用于限定所有者SID,DACL和SACL)AccessToken,用来控制对安全对象的访问,访问令牌包含登录会话的安全信息,主要用来标识用户,用户组的权限。系统在用户登录时创建访问令牌,并且该用户执行的每个进程都具有该令牌的副本注意1:SACL主要用于审核和记录访问的,DACL才是具体的权限列表,所以我们平时讲的ACL通常是指DACL注意2:SD是为了方便编程提出的概念(一个结构体而已),实际上操作系统是利用AccessToken和ACL来确定对某个文件、进程等的访问权限权限检查过程每个计算机账户在登录是都会获得一个访问令牌AccessToken,这个令牌会说明当前用户的权限!而每个文件或其它对象都有它自己的访问控制列表ACL,即说明哪些账户拥有哪些权限!当该账户尝试读取或改写某个文件时,操作系统会将当前账户的访问令牌权限和目标文件每个具体的权限(ACE)按顺序作比较(只与SID相同的ACE进行比较),直到发生以下事件:一、拒绝访问的ACE明确拒绝对线程访问令牌中列出的其中一个受托者请求的任何访问权限二、线程访问令牌中列出的受托者的一个或多个允许访问的ACE明确授予所有请求的访问权限三、已检查所有ACE,并且仍然至少有一个未明确允许的请求访问权限,在这种情况下,隐式拒绝访问注意:访问控制列表ACL中的ACE有几大原则(拒绝大于允许、权限最小化、权限继承性以及权限累加)动手实践查看文件ACL讲了半天ACL是不是感觉太抽象了,来实际看看什么是ACL吧!你只需要在任意文件上右键-属性-安全-高级就能看到该文件的ACL了!其中权限选项卡中就是DACL,审核选项卡中就是SACL,所有者拥有对DACL的完全控制权其中SYSTEM用户组拥有对该文件的读取权限,这样一条具体的某个用户的某项权限就是ACL中的访问控制条目(ACE)简单修改权限修改当前用户组对某个文件只有读取权限,假如当前用户组是管理员的话还需要修改Administrators组的权限!第一步右键-属性-安全并选中当前用户点击编辑第二步只勾选允许-读取,发现不可勾选第三步禁用继承,必须要禁用继承否则不可更改,点击高级-更改权限并取消勾选包括可从该对象的父项继承的权限,弹窗选择添加,然后确定第四步重复第二步,并更改Administrators组的权限第五步尝试改写该文件,会提示没有权限注意:文件夹拥有继承和传播属性,文件拥有继承属性,继承属性很好理解就是直接复制父目录的ACL,传播就是当前文件夹是否允许子文件或子文件夹继承FkUpdate核心讲解服务相关开启关闭服务,必须用到的几个API:OpenSCManagerOpenServiceStartServiceControlServiceQueryServiceStatusChangeServiceConfigCloseServiceHandle注册表ACL相关核心API:GetNamedSecurityInfoSetNamedSecurityInfoSetEntriesInAclGetExplicitEntriesFromAclAllocateAndInitializeSidDeleteAce具体思路禁用自动更新:第一步停止Update服务,第二步Update启动状态改为禁用,第三步Update注册表所有者改为当前用户,第四步禁用继承并添加,第五步修改所有用户组的权限为只读,第六步注册表所有者改为SYSTEM恢复自动更新:第一步Update注册表所有者改为当前用户,第二步删除所有ACL,第三步启用继承,第四步注册表所有者改为SYSTEM,第五步Update服务状态改为自动,第六步启动Update服务BOOL enableUpdate() { changeObjectOwner(updateReg, FALSE); enInherit(updateReg); changeObjectOwner(updateReg, TRUE); changeStartType(updateServ, SERVICE_AUTO_START); startSrv(updateServ); return TRUE;}BOOL disableUpdate() { PACL pOldDACL = NULL, pNewDACL = NULL; DWORD dwRes = 0, dwSize = 0, i = 0; PSECURITY_DESCRIPTOR pSD; SID_NAME_USE eUse = SidTypeUnknown; PEXPLICIT_ACCESS pEa; ULONG uCount; stopSrv(updateServ); changeStartType(updateServ, SERVICE_DISABLED); changeObjectOwner(updateReg, FALSE); // disInheritDelete(updateReg); enInherit(updateReg); disInheritCopy(updateReg); dwRes = GetNamedSecurityInfo(updateReg, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD); if (dwRes != ERROR_SUCCESS) { printf(“GetNamedSecurityInfo Error %u\n”, dwRes); return FALSE; } if (ERROR_SUCCESS == GetExplicitEntriesFromAcl(pOldDACL, &uCount, &pEa)) { for (i = 0; i < uCount; i++) { pEa[i].grfAccessPermissions = GENERIC_READ; } } if (ERROR_SUCCESS != SetEntriesInAcl(uCount, pEa, NULL, &pNewDACL)) { printf(“Failed SetEntriesInAcl\n”); return FALSE; } dwRes = SetNamedSecurityInfo(updateReg, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL); if (ERROR_SUCCESS == dwRes) { printf(“Successfully Changed DACL\n”); } changeObjectOwner(updateReg, TRUE); if (pOldDACL) LocalFree(pOldDACL); if (pNewDACL) LocalFree(pNewDACL); if (pSD) LocalFree(pSD); if(pEa) LocalFree(pEa); return TRUE;}FileLocker核心讲解文件相关核心API:GetFileAttributessplitPath(自己封装路径分割)ACL相关核心API:GetNamedSecurityInfoSetNamedSecurityInfoSetEntriesInAclGetExplicitEntriesFromAclAllocateAndInitializeSidDeleteAce核心思路锁文件:第一步获取上层目录的路径,第二步上层目录禁用继承,第三步上层目录设置拒绝删除子文件的属性,第四步当前文件禁用继承,第五步当前文件添加拒绝删除的属性,第六步更改文件所有者为SYSTEM恢复文件:第一步获取上层目录的路径,第二步上层目录启用继承并删除之前的ACL,第三步当前文件启用继承并删除之前的ACL,第四步更改文件的所有者为SYSTEMBOOL lockFile(LPTSTR lpMyFile) { DWORD dwRes, i; PACL pOldDACL = NULL, pNewDACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; PEXPLICIT_ACCESS pEa; ULONG uCount; CHAR lpFileName[MAX_PATH] = { 0 }; /* 首先得到上层目录路径 / splitPath(lpMyFile, lpFileName); / 上层目录拥有者改为Admin / changeObjectOwner(lpFileName, FALSE); / 禁止上层目录继承 / disInheritCopy(lpFileName); / 保存一份原始DACL / dwRes = GetNamedSecurityInfo(lpFileName, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD); if (dwRes != ERROR_SUCCESS) { printf(“GetNamedSecurityInfo Error %u\n”, dwRes); return FALSE; } / 设置拒绝删除子文件夹的属性 / if (ERROR_SUCCESS == GetExplicitEntriesFromAcl(pOldDACL, &uCount, &pEa)) { for (i = 0; i < uCount; i++) { / public enum ACCESS_MASK { READ_FILE = 0x000001, WRITE_FILE = 0x000002, CREATE_SUBDIR = 0x000004, READ_EXT_ATTR = 0x000008, WRITE_EXT_ATTR = 0x000010, EXECUTE = 0x000020, DELETE_DIR = 0x000040, READ_FILE_ATTR = 0x000080, WRITE_FILE_ATTR = 0x000100, DELETE = 0x010000, READ_SD = 0x020000, WRITE_DACL = 0x040000, WRITE_OWNER = 0x080000, SYNCHRONIZE = 0x100000, SHARE_READ = READ_FILE | READ_EXT_ATTR | EXECUTE | READ_FILE_ATTR | READ_SD | SYNCHRONIZE, SHARE_CHANGE = SHARE_READ | WRITE_FILE | CREATE_SUBDIR | WRITE_EXT_ATTR | WRITE_FILE_ATTR | DELETE, SHARE_FULL = SHARE_CHANGE | DELETE_DIR | WRITE_DACL | WRITE_OWNER } / pEa[i].grfAccessPermissions = 0x40; pEa[i].grfAccessMode = DENY_ACCESS; pEa[i].grfInheritance = NO_INHERITANCE; } } if (ERROR_SUCCESS != SetEntriesInAcl(uCount, pEa, pOldDACL, &pNewDACL)) { printf(“Failed SetEntriesInAcl\n”); return FALSE; } / 设置新的DACL / dwRes = SetNamedSecurityInfo(lpFileName, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL); if (dwRes != ERROR_SUCCESS) { printf(“SetNamedSecurityInfo Error %u\n”, dwRes); return FALSE; } / 上层目录拥有者改回System / changeObjectOwner(lpFileName, TRUE); / 当前文件或目录的拥有者改为Admin / changeObjectOwner(lpMyFile, FALSE); / 当前文件或目录禁止继承 / disInheritCopy(lpMyFile); / 保留当前文件或目录的DACL / dwRes = GetNamedSecurityInfo(lpMyFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD); if (dwRes != ERROR_SUCCESS) { printf(“GetNamedSecurityInfo Error %u\n”, dwRes); return FALSE; } / 设置拒绝属性 / if (ERROR_SUCCESS == GetExplicitEntriesFromAcl(pOldDACL, &uCount, &pEa)) { for (i = 0; i < uCount; i++) { pEa[i].grfAccessPermissions = DELETE; pEa[i].grfAccessMode = DENY_ACCESS; pEa[i].grfInheritance = NO_INHERITANCE; } } if (ERROR_SUCCESS != SetEntriesInAcl(uCount, pEa, pOldDACL, &pNewDACL)) { printf(“Failed SetEntriesInAcl\n”); return FALSE; } / 设置新的DACL / dwRes = SetNamedSecurityInfo(lpMyFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL); if (dwRes != ERROR_SUCCESS) { printf(“SetNamedSecurityInfo Error %u\n”, dwRes); return FALSE; } changeObjectOwner(lpMyFile, TRUE); / SECURITY_DESCRIPTOR SD; InitializeSecurityDescriptor(&SD, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&SD, TRUE, NULL, FALSE); / if (pOldDACL) LocalFree(pOldDACL); if (pNewDACL) LocalFree(pNewDACL); if (pSD) LocalFree(pSD); if (pEa) LocalFree(pEa); return TRUE;}BOOL recoveryFile(LPTSTR lpMyFile) { CHAR lpFileName[MAX_PATH] = { 0 }; / 首先得到上层目录路径 */ splitPath(lpMyFile, lpFileName); changeObjectOwner(lpFileName, FALSE); enInherit(lpFileName); changeObjectOwner(lpFileName, TRUE); changeObjectOwner(lpMyFile, FALSE); enInherit(lpMyFile); changeObjectOwner(lpMyFile, TRUE); return TRUE;}END ...

March 13, 2019 · 3 min · jiezi

Python 开发比特币教程汇总

创建一个接受消息的机器人机器人接受比特币并立即退还用户创建比特币钱包其他编程语言比特币开发教程如下:PHP 比特币开发教程Go 比特币开发教程Java 比特币开发教程Node.js 比特币开发教程C# 比特币开发教程Mixin Network 开发者资源汇总

March 13, 2019 · 1 min · jiezi

基于Mixin Network的Go语言比特币开发系列教程汇总

创建机器人机器人收比特币,发比特币创建独立的比特币钱包,查余额,转账其他编程语言比特币开发教程如下:PHP 比特币开发教程Python 比特币开发教程Java 比特币开发教程Node.js 比特币开发教程开发者资源汇总

March 9, 2019 · 1 min · jiezi

基于Mixin Network的PHP比特币开发教程: 创建比特币钱包

我们已经创建过一个回复消息的机器人和一个能自动支付比特币的机器人.通过本教程的学习,你可以学到如下内容如何创建一个比特币钱包.如何读取比特币钱包的余额.如何支付比特币并即时确认.如何将Mixin Network的比特币提现到你的冷钱包或第三方交易所.前期准备:你要有一个Mixin Network账户。如果没有账户,一行代码就能创建一个$user_info = $mixinSdk->Network()->createUser(“Tom cat”);上面的语句会在本地创建一个RSA密钥对,然后调用Mixin Network来创建帐号,最后输出帐号信息.//Create User api include all account informationprint_r($user_info);print($user_info[“pubKey”]);$newConfig = array();$newConfig[“private_key”] = $user_info[“priKey”];$newConfig[“pin_token”] = $user_info[“pin_token”];$newConfig[“session_id”] = $user_info[“session_id”];$newConfig[“client_id”] = $user_info[“user_id”];帐号创建成功后结果如下:Array( [type] => user [user_id] => de06f952-6ec7-3789-8467-9aa79869a6ef [identity_number] => 0 [full_name] => Tom cat [avatar_url] => [relationship] => [mute_until] => 0001-01-01T00:00:00Z [created_at] => 2019-02-20T12:29:29.86008273Z [is_verified] => [session_id] => bc9293e5-ed9a-48da-99f9-915f561a1c60 [phone] => [pin_token] => TIPyCtRTTYOg2sr+lu0z2D3xS8SOtQAy0ZDnacRrn6u2ytutZinzeEpRTD9N1+DS/T1zJ8VoX4ED19nhF5SApjqjUaRjKI5lga4rQGcePjCvM0D89FdpmKJzNMLjzV2DglKFMPbnJTu1btfILc0XWiSNEiiFr2mHuLI7bYuQzWI= [invitation_code] => [code_id] => [code_url] => https://mixin.one/codes/ [has_pin] => [receive_message_source] => EVERYBODY [accept_conversation_source] => EVERYBODY [priKey] => —–BEGIN PRIVATE KEY—–MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALh0dSy2GcKek/Jp4lTMZxJ30AWP+inZ4c+FG+3ch3fenmXysCyM56hgvVZwh4RrRpvVjRt/NNE3k2WgN9LNZqWXCmo4ae/hJjpwuj/EVR/1/HSebF9hcvMoTre8D0iLlk+rf1tgr/ZHmIoa8ef45xMBDargfsF4b5k7kUavU9/xAgMBAAECgYB1ShBMOwsMVxvKdIvn0gXkl20ebFvtis9szr5gtO8rSNK+DuD5oyuXRNSAh5OUn0ZJxzQv/OZP9x/x6jw0/kk7Aj6cjjN3beC7UoayDYms4yNFoWNPqZEXkQ0b2tRsF3mdNj6LVm6Gq7FPDD1TYJ4GR4eOcWHCkZWym26HbZ30AQJBAPNFeZ7nd9wQIzu0wN9isrZebnCko3yax64MDsUAsrmPB1wdHkdX0tJpCldighYD10Cyi+nSz3ODmmbPbLu8AjECQQDCGyi0lpCoV+skLVR04weU99Msz1neqOw1khQCJLzUW8UdDhsVwfCdzCeuZrCz+gl/aZaJ6d+6rNTMp1hLionBAkBEs34hTiUfVL9egTFm5KyrrAdscFJrQhraIDWblRLkLGxbqy194GN9YIS3IO6z4OnNL58rrYlAig30sud2LSZBAkEAjuNXT7kWvBYcbwE/jtwhlLPqrK3nRlWrrLPgLsPEjb8Ql5busVGXQ1IqU+QcaCDEJRshSlzz6YOZEx6NjO5rAQJAejvW3DmTRjUSDJD8hGr9eCpKQTBDXyUEvyLIMCuRmm9Cbz0HRl4aVXOVblVWoJ6YsGvbCkSlLQCrPL2T58JTkg==—–END PRIVATE KEY—– [pubKey] => —–BEGIN PUBLIC KEY—–MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4dHUsthnCnpPyaeJUzGcSd9AFj/op2eHPhRvt3Id33p5l8rAsjOeoYL1WcIeEa0ab1Y0bfzTRN5NloDfSzWallwpqOGnv4SY6cLo/xFUf9fx0nmxfYXLzKE63vA9Ii5ZPq39bYK/2R5iKGvHn+OcTAQ2q4H7BeG+ZO5FGr1Pf8QIDAQAB—–END PUBLIC KEY—–)现在你需要小心保管好你的帐号信息,在读取该账户的比特币资产余额或者进行其他操作时,将需要用到这些信息.给新建的帐号创建一个比特币钱包新账号并不默认内置比特币钱包, 现在读一下比特币余额就可以创建一个比特币钱包。$asset_infoNew = $mixinSdkNew->Wallet()->readAsset(“c6d0c728-2624-429b-8e0d-d9d19b6592fa”);echo “BitCoin wallet address is :”.$asset_infoNew[“public_key”];创建的帐号的比特币资产详细信息如下,其中public key就是比特币的存币地址:Array( [type] => asset [asset_id] => c6d0c728-2624-429b-8e0d-d9d19b6592fa [chain_id] => c6d0c728-2624-429b-8e0d-d9d19b6592fa [symbol] => BTC [name] => Bitcoin [icon_url] => https://images.mixin.one/HvYGJsV5TGeZ-X9Ek3FEQohQZ3fE9LBEBGcOcn4c4BNHovP4fW4YB97Dg5LcXoQ1hUjMEgjbl1DPlKg1TW7kK6XP=s128 [balance] => 0 [public_key] => 195p8R8Y15uzDGMrdVkELVUW2444psqiSq [account_name] => [account_tag] => [price_btc] => 1 [price_usd] => 3928.11498197 [change_btc] => 0 [change_usd] => -0.006841408545228452 [asset_key] => c6d0c728-2624-429b-8e0d-d9d19b6592fa [confirmations] => 12 [capitalization] => 0)这个API能够提供若干与比特币有关的信息:存币地址:[public_key]Logo: [icon_url]资产名字:[name]资产在Mixin Network的uuid: [asset_key]对美元的价格(Coinmarketcap.com提供): [price_usd]存币时确认的区块数量:[confirmations]比特币私钥呢?比特币的私钥呢?这个私钥被Mixin Network通过多重签名保护,所以对用户来说是不可见的,比特币资产的提现和转账都需要用户提供正确的的RSA签名,PIN代码与会话密钥才能完成.不只是比特币,还有以太坊,EOS等这个帐号不只支持比特币,还支持以太坊,EOS等, 完整的区块链支持列表. 这个账户同时也支持所有的 ERC20 代币与 EOS 代币.创建其它的币的钱包与创建比特币钱包过程一样,读对应的资产余额就可以.Mixin Network 当前支持的加密货币 (2019-02-19)cryptouuid in Mixin NetworkEOS6cfe566e-4aad-470b-8c9a-2fd35b49c68dCNB965e5c6e-434c-3fa9-b780-c50f43cd955cBTCc6d0c728-2624-429b-8e0d-d9d19b6592faETC2204c1ee-0ea2-4add-bb9a-b3719cfff93aXRP23dfb5a5-5d7b-48b6-905f-3970e3176e27XEM27921032-f73e-434e-955f-43d55672ee31ETH43d61dcd-e413-450d-80b8-101d5e903357DASH6472e7e3-75fd-48b6-b1dc-28d294ee1476DOGE6770a1e5-6086-44d5-b60f-545f9d9e8ffdLTC76c802a2-7c88-447f-a93e-c29c9e5dd9c8SC990c4c29-57e9-48f6-9819-7d986ea44985ZENa2c5d22b-62a2-4c13-b3f0-013290dbac60ZECc996abc9-d94e-4494-b1cf-2a3fd3ac5714BCHfd11b6e3-0b87-41f1-a41f-f0e9b49e5bf0EOS的存币地址与其它的币有些不同,它由两部分组成: account_name and account tag, 如果你向Mixin Network存入EOS,你需要填两项数据: account name 是eoswithmixin,备注里输入你的account_tag,比如0aa2b00fad2c69059ca1b50de2b45569. EOS的资产余额返回结果如下:Array( [type] => asset [asset_id] => 6cfe566e-4aad-470b-8c9a-2fd35b49c68d [chain_id] => 6cfe566e-4aad-470b-8c9a-2fd35b49c68d [symbol] => EOS [name] => EOS [icon_url] => https://images.mixin.one/a5dtG-IAg2IO0Zm4HxqJoQjfz-5nf1HWZ0teCyOnReMd3pmB8oEdSAXWvFHt2AJkJj5YgfyceTACjGmXnI-VyRo=s128 [balance] => 0 [public_key] => [account_name] => eoswithmixin [account_tag] => 0aa2b00fad2c69059ca1b50de2b45569 [price_btc] => 0.00097367 [price_usd] => 3.87734515 [change_btc] => 0.05950956117519646 [change_usd] => 0.07238079041492786 [asset_key] => eosio.token:EOS [confirmations] => 64 [capitalization] => 0)存入比特币与读取比特币余额现在,你可以向比特币的钱包存币了。当然,在比特币网络里转币,手续费是相当贵的,费用的中位数在0.001BTC,按当前4000美元的价格,在4美元左右,有一个方便的办法,如果你有Mixin Messenger帐号,里面并且有比特币的话,可以直接提现比特币到新创建的帐号的比特币充值地址,它们在同一个Mixin Network网络内,手续费为0,而且1秒到账。下面的代码,可以读取比特币钱包余额.$btc = $mixinSdkNew->Wallet()->readAsset(“c6d0c728-2624-429b-8e0d-d9d19b6592fa”);print_r($btc);Mixin Network网内免手续费的,并且即时确认任何币在Mixin Network内部的交易,都是无手续费的,并且立刻到账。前期准备: 账户设置了PIN对于新创建的帐号,我们通过updatePin来设置新PIN码, 代码如下://Create a PIN.$pinInfo = $mixinSdkNew->Pin()->updatePin(’’,PIN);print_r($pinInfo);Mixin Network帐号之间的比特币支付通过Mixin Messenger,我们可以先转比特币给机器人,然后让机器人转币给新用户。$mixinSdk = new MixinSDK(require ‘./config.php’);//$user_info[“user_id”] generated by create user;$trans_info = $mixinSdk->Wallet()->transfer(BTC_ASSET_ID,$user_info[“user_id”], $mixinSdk->getConfig()[‘default’][‘pin’],AMOUNT);print_r($trans_info);读取Bitcoin的余额,来确认比特币是不是转成功了! 注意$mixinSdkNew是新用户的。$btc = $mixinSdkNew->Wallet()->readAsset(BTC_ASSET_ID);print_r($btc);如何将比特币存入你的冷钱包或者第三方交易所如果你希望将币存入你的冷钱包或者第三方交易所, 先要得到冷钱包或者你在第三方交易所的钱包地址,然后将钱包地址提交到Mixin Network.要点提示: 提现是需要支付收续费的,准备好比特币包地址!增加目的钱包地址到Mixin Network调用createAddress API, 将会返回一个address_id,下一步的提现操作会用到这个id。$btcInfo = $mixinSdkNew->Wallet()->createAddress(“c6d0c728-2624-429b-8e0d-d9d19b6592fa”, “14T129GTbXXPGXXvZzVaNLRFPeHXD1C25C”, $mixinSdkNew->getConfig()[‘default’][‘pin’], “BTC withdral”,false);这里的 14T129GTbXXPGXXvZzVaNLRFPeHXD1C25C 就是一个比特币钱包地址, 如下所示,提现费用是0.0025738 BTC, address_id 是"345855b5-56a5-4f3b-ba9e-d99601ef86c1".Array( [type] => address [address_id] => 345855b5-56a5-4f3b-ba9e-d99601ef86c1 [asset_id] => c6d0c728-2624-429b-8e0d-d9d19b6592fa [public_key] => 14T129GTbXXPGXXvZzVaNLRFPeHXD1C25C [label] => BTC withdral [account_name] => [account_tag] => [fee] => 0.0025738 [reserve] => 0 [dust] => 0.0001 [updated_at] => 2019-02-20T01:47:56.44067294Z)创建提现地址成功后,你可以用readAddress读取最新的提现费。$wdInfo = $mixinSdkNew->Wallet()->readAddress($btcInfo[“address_id”]);提交提现请求,Mixin Network会即时处理提现请求.提交提现请求到Mixin Network, $btcInfo[“address_id”]就是createAddress创建的。$wdInfo = $mixinSdkNew->Wallet()->withdrawal($btcInfo[“address_id”], “0.01”, $mixinSdkBot->getConfig()[‘default’][‘pin’], “BTC withdral”);可以通过blockchain explore来查看进度.完整的代码在这儿 ...

March 8, 2019 · 2 min · jiezi

支付宝小程序面向个人开放了!我将以一个 Demo 为例讲解整个流程。

Hello,我是犯迷糊的小 K。目前是 ifanr 的一只前端攻城狮,同时也是知晓云团队的一员。3 月伊始,ifanr 旗下品牌——知晓云 3.0 版本正式上线。此次更新得到业内许多开发者的密切关注和积极支持,在此,我代表知晓云团队表示万分感谢哈。( ̄▽ ̄)~*知晓云是业界第一个支持多平台小程序开发的后端云服务,它免去了小程序开发中服务器搭建、域名备案、数据接口开发、线上运维等繁琐流程,让开发者更快、更低成本地做出优质的小程序。言归正传。和许多童鞋一样,小 K 使用知晓云时,也是第一次开发小程序,开发过程也是百转曲折。因此,小 K 希望通过这篇文章,和各位童鞋进行交流。毕竟,大家的学习历程是相似的,遇到的困惑也应该差不多。本文结构大致如下:谈谈如何成为支付宝小程序开发者。聊聊如何创建我的第一个支付宝小程序。以一个 Demo 为例,详细讲讲如何在支付宝小程序中接入和使用知晓云 SDK。如何成为一名支付宝小程序开发者?申请成为支付宝小程序开发者,是一件再简单不过的事儿,仅需 2 步,比把大象放进冰箱还简单。第一步,登录蚂蚁金服开放平台,注册成为小程序开发用户。此过程需要你依次完成账号信息、邮箱激活和信息登记等流程。第二步,完成上述操作后,就能进入小程序管理后台,点击创建应用并填写信息,创建成功后即可获取开发小程序的 AppID。嗯,现在小 K 已经是一枚准小程序开发者啦。(后续请进入小程序配置-设置-开发设置,根据平台的设置方式教程,配置接口加签方式,获得支付宝公钥和密钥文件)如何创建我的第一个小程序?获得了「准入资格」后,小 K 开始参照小程序官方文档,下载官方的开发者工具并创建了一个初始化的小程序。Well done!小 K 的第一个初始化小程序诞生了~ 接下来,可以看看支付宝小程序官方的体验小程序 Demo 教程文档,熟悉一下小程序代码组织方式和开发特性。现在,有了开发工具和基础知识积累,可以试试 freestyle 咯。唯一的问题是:小 K 应该选择什么类型的小程序作为 Demo 呢?对于 Demo 选择,唯一的原则就是精简「简」是像小 K 这样的小白开发者一看就懂。「精」是尽可能在有限的代码中,体现知晓云功能的强大性。于是,我选择了个经典的 TodoMVC 的小程序——「我的书架」作为示例。由于「我的书架」 Demo 将知晓云的核心模块之一——数据管理的 CRUD 操作很好地展示了出来,所以,我们希望通过这个 Demo 让各位童鞋学会利用知晓云,完成常见的数据增删改查功能。如何在小程序中调用知晓云 SDK?准备工作在正式使用知晓云的 SDK 前,首先确保走完以下 2 个流程:第一,完成小程序的授权。目前,知晓云在注册模块和设置模块都有提供小程序授权操作,二者的授权流程大体一致。在这里,我们演示设置模块的小程序操作。点击应用标签,进入应用的管理面板;进入管理面板后,切换到设置模块并进入应用设置 tab 页,点击平台设置-支付宝小程序-立即开通,点击编辑并填写相关配置信息后即可完成授权。第二,在「小程序后台」配置安全域名。装载 SDK接下来,看看知晓云的 SDK 的使用说明文档。老夫掐指一算,将 SDK 的接入小程序的方法和数据表操作看了一遍,约莫花费 10 分钟。毕竟 Demo 只涉及数据操作嘛,所以要做到有的放矢,要啥看啥。下载知晓云提供的 SDK 后,将其引入小程序的 app.js 中,并通过在前面的设置模块的小程序设置 tab 页中获取当前应用的 ClientID。设计数据结构和创建数据表完成上述操作后,小 K 就可以使用 SDK 提供的各种接口,接下来思考一下「我的书架」将用到什么数据及其结构。由于是第一个 Demo ,本着精简的原则,小 K 在此就只设计了一个 bookName 的字段Tips:知晓云的数据管理模块会为每张数据表自动创建 id,create_by,create_at,update_at 和 acl 等字段。根据文档提示,在使用知晓云的数据管理模块时,需要首先提供存放数据的 tableName。因此,首先要在知晓云开发者平台创建数据表从而获取 tableName。获取 tableName 后,小 K 将其放在了 app.js 文件的 globalData 对象上,以供后面各种数据操作接口的参数调用。开始使用知晓云的 SDK小 K 在这里不会细谈「我的书架」是如何编写的,因为不同的童鞋的对这个功能的实现方式可能不一样。小 K 只会谈在哪些控件中使用知晓云提供的接口,来实现小 K 的需求——添加一本书。创建书目记录翻查了文档,发现创建一条记录很简单,只需要调用 create 创建一条空记录,然后调用 set 为上面创建的空记录赋值,最后调用 save 将创建的记录保存到服务器即可。更新一条记录有时,小 K 手抖,在输入书目的时候填写了错别字,那么理应提供一个更新记录的功能吧;知晓云提供了 update 接口,让更新数据 so easy。删除一条记录最后,当小K的书架不再存在某本书时,必然需要一个删除操作。通过调用 delete 接口就可以实现一条记录的删除操作。最后的话以上就是小 K 用知晓云烹调出的第一个支付宝小程序——「我的书架」,最主要就是用到了知晓云的数据管理功能模块。当然,知晓云还提供作为 BaaS 产品的基础文件上传和数据统计功能等,同时具备贴切小程序的特性功能,譬如支付宝支付和富文本编辑功能。*除了「我的书架」 Demo 外,知晓云官方还提供了知晓云 SDK 官方示例小程序,用于演示 SDK 更丰富的接口使用方法。代码已开源在 ifanrX 的 GitHub 上,链接:https://github.com/ifanrx/hyd… 有兴趣的童鞋可以 star 或是 fork 一下。本文首发于「知晓云」公众号:https://mp.weixin.qq.com/s/Vk…知晓云是国内首家专注于小程序开发的后端云服务。使用知晓云,小程序开发快人一步。 ...

March 5, 2019 · 1 min · jiezi

基于Mixin Network的Go语言比特币开发教程 : 用 Mixin Messenger 机器人接受和发送比特币

基于Mixin Network的Go语言比特币开发教程 : 用 Mixin Messenger 机器人接受和发送比特币在 上一篇教程中, 我们创建了自动回复消息的机器人,当用户发送消息"Hello,World!“时,机器人会自动回复同一条消息!按本篇教程后学习后完成后,你的机器人将会接受用户发送过来的加密货币,然后立即转回用户。完整代码如下:main.gofpackage mainimport ( “context” “encoding/base64” “encoding/json” “log” “github.com/MooooonStar/mixin-sdk-go/messenger” mixin “github.com/MooooonStar/mixin-sdk-go/network”)type Listener struct { *messenger.Messenger}// interface to implement if you want to handle the messagefunc (l *Listener) OnMessage(ctx context.Context, msg messenger.MessageView, userId string) error { data, err := base64.StdEncoding.DecodeString(msg.Data) if err != nil { return err } if msg.Category == “SYSTEM_ACCOUNT_SNAPSHOT” { var transfer messenger.TransferView if err := json.Unmarshal(data, &transfer); err != nil { return err } log.Println(“I got a coin: “, transfer.Amount) mixin.Transfer(msg.UserId,transfer.Amount,transfer.AssetId,”",messenger.UuidNewV4().String(), PinCode,PinToken,UserId,SessionId,PrivateKey) return nil // return l.SendPlainText(ctx, msg.ConversationId, msg.UserId, string(data)) } else if msg.Category == “PLAIN_TEXT” { log.Printf(“I got a message, it said: %s”, string(data)) if string(data) == “g” { payLinkEOS := “https://mixin.one/pay?recipient=" + msg.UserId + “&asset=” + “6cfe566e-4aad-470b-8c9a-2fd35b49c68d” + “&amount=” + “0.1” + “&trace=” + messenger.UuidNewV4().String() + “&memo=” payLinkBTC := “https://mixin.one/pay?recipient=" + msg.UserId + “&asset=” + “c6d0c728-2624-429b-8e0d-d9d19b6592fa” + “&amount=” + “0.001” + “&trace=” + messenger.UuidNewV4().String() + “&memo=” log.Println(payLinkBTC) BtnEOS := messenger.Button{Label: “Pay EOS 0.1”, Color: “#0080FF”, Action: payLinkEOS} BtnBTC := messenger.Button{Label: “Pay BTC 0.0001”, Color: “#00FF80”, Action: payLinkBTC} if err := l.SendAppButtons(ctx, msg.ConversationId, msg.UserId, BtnEOS, BtnBTC); err != nil { return err } return nil } else if string(data) == “a” { card := messenger.AppCard{Title: “Pay BTC 0.0001”, Description: “topay”, Action: “http://www.google.cn”, IconUrl: “https://images.mixin.one/HvYGJsV5TGeZ-X9Ek3FEQohQZ3fE9LBEBGcOcn4c4BNHovP4fW4YB97Dg5LcXoQ1hUjMEgjbl1DPlKg1TW7kK6XP=s128"} if err := l.SendAppCard(ctx, msg.ConversationId, msg.UserId, card); err != nil { return err } return nil } else if string(data) == “r” { mixin.Transfer(msg.UserId,“0.0001”,“c6d0c728-2624-429b-8e0d-d9d19b6592fa”,”",messenger.UuidNewV4().String(), PinCode,PinToken,UserId,SessionId,PrivateKey) return nil } else { return l.SendPlainText(ctx, msg.ConversationId, msg.UserId, string(data)) } } else { log.Println(“Unknown message!”, msg.Category) return err }}const ( UserId = “21042518-85c7-4903-bb19-f311813d1f51” PinCode = “911424” SessionId = “4267b63d-3daa-449e-bc13-970aa0357776” PinToken = “gUUxpm3fPRVkKZNwA/gk10SHHDtR8LmxO+N6KbsZ/jymmwwVitUHKgLbk1NISdN8jBvsYJgF/5hbkxNnCJER5XAZ0Y35gsAxBOgcFN8otsV6F0FAm5TnWN8YYCqeFnXYJnqmI30IXJTAgMhliLj7iZsvyY/3htaHUUuN5pQ5F5s=” //please delele the blank of PrivateKey the before each line PrivateKey = -----BEGIN RSA PRIVATE KEY-----MIICXQIBAAKBgQCDXiWJRLe9BzPtXmcVe6acaFTY9Ogb4Hc2VHFjKFsp7QRVCytx3KC/LRojTFViwwExaANTZQ6ectwpAxIvzeYeHDZCXCh6JRFIYK/ZuREmYPcPQEWDs92Tv/4XTAdTH8l9UJ4VQY4zwqYMak237N9xEvowT0eR8lpeJG0jAjN97QIDAQABAoGADvORLB1hGCeQtmxvKRfIr7aEKak+HaYfi1RzD0kRjyUFwDQkPrJQrVGRzwCqGzJ8mUXwUvaGgmwqOJS75ir2DL8KPz7UfgQnSsHDUwKqUzULgW6nd/3OdDTYWWaNcDjbkEpsVchOpcdkywvZhhyGXszpM20Vr8emlBcFUOTfpTUCQQDVVjkeMcpRsImVU3tPYyiuqADhBTcgPBb+Ownk/87jyKF1CZOPvJAebNmpfJP0RMxUVvT4B9/U/yxZWNLhLtCXAkEAnaOEuefUxGdE8/55dUTEb7xrr22mNqykJaax3zFK+hSFBrM3gUY5fEETtHnl4gEdX4jCPybRVc1JSFY/GWoyGwJBAKoLti95JHkErEXYavuWYEEHLNwvmgcZnoI6cOKVfEVYEEoHvhTeCkoWHVDZOd2EURIQ1eY18JYIZ0M4Z66R8DUCQCsKiKTR3dA6eiM8qiEQw6nWgniFscpf3PnCx/Iu3U/m5mNr743GhM+eXSj7136b209IYfEoQiPxRz8O/W+NBV0CQQDVPxqJlFD34MC9aQN42l3NV1hDsl1+nSkWkXSyhhNRMpobtV1a7IgJGyt5HxBzgNlBNOayICRf0rRjvCdw6aTP-----END RSA PRIVATE KEY-----)func main() { ctx := context.Background() m := messenger.NewMessenger(UserId, SessionId, PrivateKey) l := &Listener{m} go m.Run(ctx, l) select {}}你好, 比特币!在项目目录下编译并执行cd mixin_labs-go-botgo build./mixin_labs-go-bot开发者可以通过消息面板,给机器人转比特币,当机器人收到比特币后,马上返还给用户!事实上,用户可以发送任意的币种给机器人,它都能马上返还!源代码解释if msg.Category == “SYSTEM_ACCOUNT_SNAPSHOT” { var transfer messenger.TransferView if err := json.Unmarshal(data, &transfer); err != nil { return err } log.Println(“I got a coin: “, transfer.Amount) mixin.Transfer(msg.UserId,transfer.Amount,transfer.AssetId,”",messenger.UuidNewV4().String(), PinCode,PinToken,UserId,SessionId,PrivateKey) return nil // return l.SendPlainText(ctx, msg.ConversationId, msg.UserId, string(data))}调用SDK的 mixin.Transfer 将币返还用户!高级用法APP_BUTTON_GROUP在一些应用场景,比如:有一个交易所想提供换币服务,将比特币换成以太坊,EOS,比特币现金等,你想显示给用户一组按钮,它们分别代表不同的币与不同的数量,APP_BUTTON_GROUP可以帮你做到这一点.payLinkEOS := “https://mixin.one/pay?recipient=" + msg.UserId + “&asset=” + “6cfe566e-4aad-470b-8c9a-2fd35b49c68d” + “&amount=” + “0.1” + “&trace=” + messenger.UuidNewV4().String() + “&memo=“payLinkBTC := “https://mixin.one/pay?recipient=" + msg.UserId + “&asset=” + “c6d0c728-2624-429b-8e0d-d9d19b6592fa” + “&amount=” + “0.001” + “&trace=” + messenger.UuidNewV4().String() + “&memo=“log.Println(payLinkBTC)BtnEOS := messenger.Button{Label: “Pay EOS 0.1”, Color: “#0080FF”, Action: payLinkEOS}BtnBTC := messenger.Button{Label: “Pay BTC 0.001”, Color: “#00FF80”, Action: payLinkBTC}if err := l.SendAppButtons(ctx, msg.ConversationId, msg.UserId, BtnEOS, BtnBTC); err != nil { return err}这里演示给用户BTC与EOS两种,你还可以增加更多的按钮.APP_CARD如果你觉得一组按钮太单调了,可以试一下APP_CARD,它提供一个图标的链接card := messenger.AppCard{Title: “CNB”, Description: “Chui Niu Bi”, Action: “http://www.google.cn”, IconUrl: “https://images.mixin.one/0sQY63dDMkWTURkJVjowWY6Le4ICjAFuu3ANVyZA4uI3UdkbuOT5fjJUT82ArNYmZvVcxDXyNjxoOv0TAYbQTNKS=s128"}if err := l.SendAppCard(ctx, msg.ConversationId, msg.UserId, card); err != nil { return err}Full source code ...

March 4, 2019 · 3 min · jiezi

Python 比特币教程之三: 创建比特币钱包,读余额,极速免费转账,标准转账

我们已经创建过一个回复消息的机器人和一个能自动支付比特币的机器人.通过本教程的学习,你可以学到如下内容如何创建一个比特币钱包.如何读取比特币钱包的余额.如何实现免手续费支付比特币并1秒到账如何将Mixin Network的比特币提现到你的冷钱包或第三方交易所.通过Mixin Network Python SDK创建一个比特币钱包前期准备:你要有一个Mixin Network账户。如果没有账户,一行代码就能创建一个 userInfo = mixinApiBotInstance.createUser(session_key.decode(),“Tom Bot”)上面的语句会在本地创建一个RSA密钥对,然后调用Mixin Network来创建帐号,最后输出帐号信息.//Create User api include all account informationuserInfo.get(“data”).get(“pin_token”),userInfo.get(“data”).get(“session_id”),userInfo.get(“data”).get(“user_id”),帐号创建成功后结果如下:{‘data’: {’type’: ‘user’, ‘user_id’: ‘2f25b669-15e7-392c-a1d5-fe7ba43bdf37’,‘identity_number’: ‘0’, ‘full_name’: ‘Tom Bot’, ‘avatar_url’: ‘’,‘relationship’: ‘’, ‘mute_until’: ‘0001-01-01T00:00:00Z’,‘created_at’: ‘2019-02-22T06:23:41.754573722Z’, ‘is_verified’: False,‘session_id’: ‘284c7b39-3284-4cf6-9354-87df30ec7d57’, ‘phone’: ‘’,‘pin_token’: ‘g4upUgBXa8ATk7yxL6B94HgI4GV4sG4t8Wyn6uTu2Q2scH11UMQ5bYDb6Md+3LRQqRjEdRFcLlHijXGBihRweTaKTZjHQqolWbZcffesVIias6WppV/QMu4TzXCuKa5xpj3uhjL+yPyfWTLGUaVJTJN9n7PQmHSIUBXrovbfodk=’,‘invitation_code’: ‘’, ‘code_id’: ‘’, ‘code_url’: ‘’, ‘has_pin’: False,‘receive_message_source’: ‘EVERYBODY’, ‘accept_conversation_source’: ‘EVERYBODY’}}现在你需要小心保管好你的帐号信息,在读取该账户的比特币资产余额或者进行其他操作时,将需要用到这些信息.给新建的帐号创建一个比特币钱包新账号并不默认内置比特币钱包, 现在读一下比特币余额就可以创建一个比特币钱包。def readAssetAddress(asset_id,isBTC = True): with open(’new_users.csv’, newline=’’) as csvfile: reader = csv.reader(csvfile) for row in reader: pin = row.pop() userid = row.pop() session_id = row.pop() pin_token = row.pop() private_key = row.pop() mixinApiNewUserInstance = generateMixinAPI(private_key, pin_token, session_id, userid, pin,"") btcInfo = mixinApiNewUserInstance.getAsset(asset_id) print(btcInfo) if isBTC: print(“Account %s 's Bitcoin wallet address is %s " %(userid,btcInfo.get(“data”).get(“public_key”))) else: print(“Account %s 's EOS account name is %s, wallet address is %s " %(userid, btcInfo.get(“data”).get(“account_name”), btcInfo.get(“data”).get(“account_tag”)))创建的帐号的比特币资产详细信息如下,其中public key就是比特币的存币地址:{‘data’: {’type’: ‘asset’, ‘asset_id’: ‘c6d0c728-2624-429b-8e0d-d9d19b6592fa’,‘chain_id’: ‘c6d0c728-2624-429b-8e0d-d9d19b6592fa’,‘symbol’: ‘BTC’, ’name’: ‘Bitcoin’,‘icon_url’: ‘https://images.mixin.one/HvYGJsV5TGeZ-X9Ek3FEQohQZ3fE9LBEBGcOcn4c4BNHovP4fW4YB97Dg5LcXoQ1hUjMEgjbl1DPlKg1TW7kK6XP=s128','balance': ‘0’,‘public_key’: ‘12sJHR7HJPMt33KwSHyxQvYqGGUEbVGREf’,‘account_name’: ‘’, ‘account_tag’: ‘’, ‘price_btc’: ‘1’,‘price_usd’: ‘3879.88117389’, ‘change_btc’: ‘0’,‘change_usd’: ‘0.017333475714793264’,‘asset_key’: ‘c6d0c728-2624-429b-8e0d-d9d19b6592fa’,‘confirmations’: 12, ‘capitalization’: 0}}Account a8cefb2e-cb93-338f-aba7-32a3a635ad02 ’s Bitcoin wallet address is 12sJHR7HJPMt33KwSHyxQvYqGGUEbVGREf这个API能够提供若干与比特币有关的信息:存币地址:[public_key]Logo: [icon_url]资产名字:[name]资产在Mixin Network的uuid: [asset_key]对美元的价格(Coinmarketcap.com提供): [price_usd]存币时确认的区块数量:[confirmations]比特币私钥呢?比特币的私钥呢?这个私钥被Mixin Network通过多重签名保护,所以对用户来说是不可见的,比特币资产的提现和转账都需要用户提供正确的的RSA签名,PIN代码与会话密钥才能完成.不只是比特币,还有以太坊,EOS等这个帐号不只支持比特币,还支持以太坊,EOS等, 完整的区块链支持列表. 这个账户同时也支持所有的 ERC20 代币与 EOS 代币.创建其它的币的钱包与创建比特币钱包过程一样,读对应的资产余额就可以.Mixin Network 当前支持的加密货币 (2019-02-19)cryptouuid in Mixin NetworkEOS6cfe566e-4aad-470b-8c9a-2fd35b49c68dCNB965e5c6e-434c-3fa9-b780-c50f43cd955cBTCc6d0c728-2624-429b-8e0d-d9d19b6592faETC2204c1ee-0ea2-4add-bb9a-b3719cfff93aXRP23dfb5a5-5d7b-48b6-905f-3970e3176e27XEM27921032-f73e-434e-955f-43d55672ee31ETH43d61dcd-e413-450d-80b8-101d5e903357DASH6472e7e3-75fd-48b6-b1dc-28d294ee1476DOGE6770a1e5-6086-44d5-b60f-545f9d9e8ffdLTC76c802a2-7c88-447f-a93e-c29c9e5dd9c8SC990c4c29-57e9-48f6-9819-7d986ea44985ZENa2c5d22b-62a2-4c13-b3f0-013290dbac60ZECc996abc9-d94e-4494-b1cf-2a3fd3ac5714BCHfd11b6e3-0b87-41f1-a41f-f0e9b49e5bf0EOS的存币地址与其它的币有些不同,它由两部分组成: account_name and account tag, 如果你向Mixin Network存入EOS,你需要填两项数据: account name 是eoswithmixin,备注里输入你的account_tag,比如0aa2b00fad2c69059ca1b50de2b45569.EOS的资产余额返回结果如下:{‘data’: {’type’: ‘asset’, ‘asset_id’: ‘6cfe566e-4aad-470b-8c9a-2fd35b49c68d’,‘chain_id’: ‘6cfe566e-4aad-470b-8c9a-2fd35b49c68d’,‘symbol’: ‘EOS’, ’name’: ‘EOS’,‘icon_url’: ‘https://images.mixin.one/a5dtG-IAg2IO0Zm4HxqJoQjfz-5nf1HWZ0teCyOnReMd3pmB8oEdSAXWvFHt2AJkJj5YgfyceTACjGmXnI-VyRo=s128','balance': ‘0’, ‘public_key’: ‘’,‘account_name’: ’eoswithmixin’, ‘account_tag’: ‘70dae97b661ca9f80cb0e6549feeba6c’,‘price_btc’: ‘0.00092392’, ‘price_usd’: ‘3.58276497’,‘change_btc’: ‘-0.019294922814297986’, ‘change_usd’: ‘-0.0033825963089133683’,‘asset_key’: ’eosio.token:EOS’, ‘confirmations’: 64, ‘capitalization’: 0}}Account a8cefb2e-cb93-338f-aba7-32a3a635ad02 ’s EOS account name is eoswithmixin, wallet address is 70dae97b661ca9f80cb0e6549feeba6c存入比特币与读取比特币余额现在,你可以向比特币的钱包存币了。当然,在比特币网络里转币,手续费是相当贵的,费用的中位数在0.001BTC,按当前4000美元的价格,在4美元左右,有一个方便的办法,如果你有Mixin Messenger帐号,里面并且有比特币的话,可以直接提现比特币到新创建的帐号的比特币充值地址,它们在同一个Mixin Network网络内,手续费为0,而且1秒到账。下面的代码,可以读取比特币钱包余额.btcInfo = mixinApiNewUserInstance.getAsset(asset_id)print(“Account %s 's balance is %s " %(userid,btcInfo.get(“data”).get(“balance”)))Mixin Network网内免手续费的,并且即时确认任何币在Mixin Network内部的交易,都是无手续费的,并且立刻到账。前期准备: 账户设置了PIN对于新创建的帐号,我们通过updatePin来设置新PIN码, 代码如下:pinInfo = mixinApiNewUserInstance.updatePin(PIN,”")print(pinInfo)Mixin Network帐号之间的比特币支付通过Mixin Messenger,我们可以先转比特币给机器人,然后让机器人转币给新用户。mixinApiNewUserInstance = generateMixinAPI(private_key, pin_token, session_id, userid, pin,”")btcInfo = mixinApiBotInstance.transferTo(MASTER_UUID, BTC_ASSET_ID, AMOUNT, “")print(btcInfo)读取Bitcoin的余额,来确认比特币是不是转成功了! 注意$mixinSdkNew是新用户的。btcInfo = mixinApiNewUserInstance.getAsset(asset_id)print(“Account %s 's balance is %s " %(userid,btcInfo.get(“data”).get(“balance”)))如何将比特币存入你的冷钱包或者第三方交易所如果你希望将币存入你的冷钱包或者第三方交易所, 先要得到冷钱包或者你在第三方交易所的钱包地址,然后将钱包地址提交到Mixin Network.要点提示: 提现是需要支付收续费的,准备好比特币包地址!增加目的钱包地址到Mixin Network调用createAddress API, 将会返回一个address_id,下一步的提现操作会用到这个id。BTC_ASSET_ID = “c6d0c728-2624-429b-8e0d-d9d19b6592fa”;EOS_ASSET_ID = “6cfe566e-4aad-470b-8c9a-2fd35b49c68d”;BTC_WALLET_ADDR = “14T129GTbXXPGXXvZzVaNLRFPeHXD1C25C”;btcInfo = mixinApiBotInstance.createAddress(BTC_ASSET_ID, BTC_WALLET_ADDR,“BTC”,””,”")print(btcInfo)这里的 14T129GTbXXPGXXvZzVaNLRFPeHXD1C25C 就是一个比特币钱包地址, 如下所示,提现费用是0.0034802 BTC, address_id 是"345855b5-56a5-4f3b-ba9e-d99601ef86c1".{‘data’: {’type’: ‘address’,‘address_id’: ‘47998e2f-2761-45ce-9a6c-6f167b20c78b’,‘asset_id’: ‘c6d0c728-2624-429b-8e0d-d9d19b6592fa’,‘public_key’: ‘14T129GTbXXPGXXvZzVaNLRFPeHXD1C25C’, ’label’: ‘BTC’,‘account_name’: ‘’, ‘account_tag’: ‘’,‘fee’: ‘0.0034802’, ‘reserve’: ‘0’, ‘dust’: ‘0.0001’,‘updated_at’: ‘2019-02-26T00:03:05.028140704Z’}}如果你操作的是EOS, 示例代码如下:EOS_ASSET_ID = “6cfe566e-4aad-470b-8c9a-2fd35b49c68d”;EOS_WALLET_ADDR = “3e2f70914c8e8abbf60040207c8aae62”;EOS_ACCOUNT_NAME = “eoswithmixin”;eosInfo = mixinApiBotInstance.createAddress(EOS_ASSET_ID, “”,"",EOS_ACCOUNT_NAME,EOS_WALLET_ADDR)print(eosInfo)创建提现地址成功后,你可以用readAddress读取最新的提现费。addr_id = btcInfo.get(“data”).get(“address_id”)addrInfo = mixinApiBotInstance.getAddress(addr_id)print(addrInfo)提交提现请求,Mixin Network会即时处理提现请求.提交提现请求到Mixin Network, $btcInfo[“address_id”]就是createAddress创建的。 mixinApiBotInstance.withdrawals(btcInfo.get(“data”).get(“address_id”),AMOUNT,"")可以通过blockchain explore来查看进度.完整的代码在这儿 ...

February 26, 2019 · 2 min · jiezi

Python 比特币教程之二: 机器人收发比特币

在上一篇教程Python 比特币 教程 之一:创建机器人中, 我们创建了自动回复消息的机器人,当用户发送消息"Hello,World!“时,机器人会自动回复同一条消息。第二课: 机器人接受比特币并立即退还用户按本篇教程后学习后完成后,你的机器人将会接受用户发送过来的加密货币,然后立即转回用户。完整代码如下:app.pyfrom mixin_ws_api import MIXIN_WS_APIfrom mixin_api import MIXIN_APIimport mixin_configimport jsonimport timefrom io import BytesIOimport base64import gziptry: import threadexcept ImportError: import _thread as threaddef on_message(ws, message): inbuffer = BytesIO(message) f = gzip.GzipFile(mode=“rb”, fileobj=inbuffer) rdata_injson = f.read() rdata_obj = json.loads(rdata_injson) print(”——-json object begin———") print(rdata_obj) print("——-json object end———") action = rdata_obj[“action”] if rdata_obj[“data”] is not None: print(“data in message:",rdata_obj[“data”]) if rdata_obj[“data”] is not None and rdata_obj[“data”][“category”] is not None: print(rdata_obj[“data”][“category”]) if action == “CREATE_MESSAGE”: data = rdata_obj[“data”] msgid = data[“message_id”] typeindata = data[“type”] categoryindata = data[“category”] userId = data[“user_id”] conversationId = data[“conversation_id”] dataindata = data[“data”] created_at = data[“created_at”] updated_at = data[“updated_at”] realData = base64.b64decode(dataindata) MIXIN_WS_API.replayMessage(ws, msgid) print(‘userId’, userId) print(“created_at”,created_at) if categoryindata == “PLAIN_TEXT”: realData = realData.decode(‘utf-8’) print(“dataindata”,realData) MIXIN_WS_API.sendUserText(ws, conversationId, userId, realData) elif categoryindata == “SYSTEM_ACCOUNT_SNAPSHOT”: rdJs = json.loads(realData) if ( float(rdJs[“amount”]) > 0 ): mixin_api.transferTo(userId, rdJs[“asset_id”], rdJs[“amount”], “")if name == “main”: mixin_api = MIXIN_API(mixin_config) mixin_ws = MIXIN_WS_API(on_message=on_message) mixin_ws.run()Hello Bitcoin!在项目目录下,执行 python app.pycd mixin_labs-python-botsource ./bin/activate(mixin_labs-python-bot) wenewzha:mixin_labs-python-bot wenewzhang$ python app.pyws open——-json object begin———{‘id’: ‘fd6ce766-331a-11e9-92a9-20c9d08850cd’, ‘action’: ‘LIST_PENDING_MESSAGES’}——-json object end———开发者可以通过消息面板,给机器人转比特币,当机器人收到比特币后,马上返还给用户!事实上,用户可以发送任意的币种给机器人,它都能马上返还!源代码解释elif categoryindata == “SYSTEM_ACCOUNT_SNAPSHOT”: rdJs = json.loads(realData) if ( float(rdJs[“amount”]) > 0 ): mixin_api.transferTo(userId, rdJs[“asset_id”], rdJs[“amount”], “")如果机器人收到币,rdJs[“amount”] 大于零;如果机器人支付币给用户,接收到的消息是一样的,唯一不同的是,rdJs[“amount”]是一个负数.最后一步,调用SDK的 mixin_api.transferTo 将币返还用户!高级用法coming soon!Mixin Network的开发资源汇编 ...

February 22, 2019 · 1 min · jiezi

Vue.js基础教程

文章链接:Vue.js基础教程开发工具准备:根据个人喜欢选择IDE,我使用的是WebStorm,推荐使用Atom和VSCode;安装git base和node.js;安装vue-cli,命令npm i -g @vue/cli;新建vue-cli项目:方法一:通过图形界面进行安装vue ui;方法二:通过命令行安装vue create project-name运行项目npm run serve,端口8080。<!–more–>双向绑定v-model双向绑定大多用于表单事件,通过监听使用者输入的事件来更新内容。现阶段大部分工作在App.vue上,template与普通写法一致,js写法:export default { name: ‘app’, data() { return { title: ‘vue.js’, myname: ‘请输入名字’ } }}去掉空白符.trim直接在v-model后加上.trim即可。<input type=“text” v-model.trim=“name” value=“name”>懒加载.lazy在离开input时才更新输入的内容,在v-model后加上.lazy即可。限定输入数字.number在v-model后加上.number即可。遍历v-for遍历有一个基本的模板:<div id=“app”> <ul v-for="(item,index) in member" :key=“index”> <li>{{item}}</li> </ul></div>组件component在App.vue中引入components中的组件:<template> <div id=“app”> <Card /> </div></template><script> import Card from ‘./components/Card’ export default { components: { Card } }</script>数据传递props<template> <div id=“app”> <Card :cardData=“cardData”/> </div></template>其中:cardData=“cardData"是这个组件的核心,用于绑定属性cardData。其他数据展示工作放在Card.vue组件中进行。JS ResultEDIT ON <template> <div class=“card_wall”> <div class=“card” v-for=“item in cardData” :key=“item.name”> <div class=“card_title”>{{item.name}}</div> <div class=“card_body”> <p>生日:{{item.birthday}}</p> <p>E-mail:{{item.mail}}</p> </div> </div> </div></template><script> export default { props: { cardData: { type: Array, required: true } } }</script>这里解析一下<div class=“card_wall”></div>包裹<div class=“card”></div>主要是方便后期应用扩展,以及让应用整体更稳定。生命周期我不喜欢用官网的生命流程图来讲解这个内容,使用文字表达更加让思维清晰。初始化:设置数据监听,编译模板,挂载到DOM并在数据变化时更新DOM等;生命周期钩子:其实就是一个过程处理,类似于服务站。生命周期钩子简介beforeCreate:实例初始化created:实例建立完成(可以取得$data)beforeMount:模板挂载之前(还没有生成html)mounted:模板挂载完成beforeUpdate:如果data发生变化,触发组件更新,重新渲染updated:更新完成beforeDestroy:实例销毁之前(实例还可以使用)destroyed:实例已销毁(所有绑定被解除、所有事件监听器被移除、所有子实例被移除)生命周期钩子用得最多的是mounted,主要用在调用属性、方法的时候,指令v-once指令第一次渲染完成后变为静态内容,其下的所有子元素都是这样的效果。v-pre指令v-pre指令会让指定元素被忽略。v-cloak指令v-cloak指令用于去除页面渲染数据时出现闪现的情况,使用方法:<template> <div id=“app”> <div v-cloak>${ item.title }</div> </div></template><style> [v-cloak] { display: none; }</style>v-html指令v-html指令会把html标签渲染成DOM显示在页面上。v-html指令只能对可信任的用户使用,否则容易受到XSS攻击。动画Vue动画一般在真正需要使用的情况下才加入页面,推荐在CSS中使用动画。加入渐变的时机v-if条件渲染v-show条件显示动态组件组件的根节点渐变的分类v-enter定义进入渐变时开始的样式。只存在组件插入前,组件插入后就移除。v-enter-active定义进入渐变的过程效果,可以设定渐变过程的时间(duration)和速度曲线(easing curve)。在组件被插入前生效,在完成动画时移除。v-enter-to定义进入渐变后结束的样式。在组件被插入后生效,同时v-enter被移除,并在完成进入渐变动画时移除。v-leave定义离开渐变时开始的样式。在触发组件离开渐变时生效,接着马上移除。v-leave-active定义离开渐变的过程效果,可以设定渐变过程的时间(duration)和速度曲线(easing curve)。在触发组件离开渐变时生效,在完成动画时移除。v-leave-to定义离开渐变后结束的样式。在触发组件离开渐变时生效,同时v-enter被移除,并在完成离开渐变动画时移除。transition自定义名称<template> <div id=“app”> <div class=“main”> <button @click=“change = !change”>縮放控制器</button> <transition name=“zoom”> <div v-if=“change” class=“ant_man_style”></div> </transition> </div> </div></template>.zoom-enter, .zoom-leave-to {width: 0px;height: 0px;}.zoom-enter-active, .zoom-leave-active {transition: width 1s, height 1s;}animation可以使用CSS中的animation动画设计更为华丽的效果。.zoom-leave-active {animation: special_effects 1.5s;}.zoom-enter-active {animation: special_effects 1.5s reverse;}@keyframes special_effects {}transition自定义动画类别除了在<transition>中设定name自定义前缀(属性),还可以预设动画类别。enter-class定义进入动画时开始的样式。enter-active-class定义进入动画的过程效果。enter-to-class定义进入动画后结束的样式。leave-class定义离开动画时开始的样式。leave-active-class定义离开动画的过程效果。leave-to-class定义离开动画后结束的样式。以上六个自定义属性优先级别高于一般渐变类别。CSS动画库:Animation.cssJavaScript钩子<transition>还可以绑定JavaScriptHooks,除了单独使用,也能结合CSS transition和animations一起使用。beforeEnter(el)在进入渐变或动画前生效。enter(el,callback)在进入渐变或动画的组件插入时生效。afterEnter(el)在进入渐变或动画结束时生效。enterCanceled(el)在未完成渐变或动画时取消。beforeLeave(el)在离开渐变或动画前生效。leaveCancelled(el)在未完成渐变或动画时取消。<transition @before-enter=“beforeEnter” @enter=“enter” @after-enter=“afterEnter” @enter-cancelled=“enterCancelled” @before-leave=“beforeLeave” @leave=“leave” @after-leave=“afterLeave” @leave-cancelled=“leaveCancelled”> <div v-if=“change” class=“ant_man_style”></div></transition>在enter和leave中必须使用done,不然它们会同时生效,动画也会瞬间完成。设定初始载入时的渐变如果想要设定一开始载入画面时组件的渐变效果,可以通过设定appear属性来实现。appear-class载入时开始的样式。appear-to-class载入过程的样式。appear-active-class载入结束时样式。<transition appear appear-class=“show-appear-class” appear-to-class=“show-appear-to-class” appear-active-class=“show-appear-active-class”></transition>先在<transition>标签内加入appear,接着类似自定义动画可以给class name命名。初始载入JavaScript HooksbeforeAppear载入前appear载入时afterAppear载入后appearCancelled取消载入(载入开始后)<div id=“app”> <transition appear @before-appear=“beforeAppear” @appear=“appear” @after-appear=“afterAppear” @appear-cancelled=“appearCancelled”> <div v-if=“change” class=“ant_man_style”></div> </transition></div>key对相同的标签元素使用key进行区分。渐变模式in-out和out-inin-out模式新加入的元素做渐变进入。渐变进入结束后,原存在的元素再渐变离开。out-in模式原存在的元素渐变离开。渐变离开结束后,新元素再渐变进入。<transition mode=“out-in”></transition><transition mode=“in-out”></transition>列表过渡<transition-group>会渲染出一个html标签,预设是<span>,也可以选择自定义tag为其他标签。无法使用(渐变模式in-out和out-in),因为不再是元素之间来回切换。每个元素需要设定一个key值,不能重复。列表乱数排序<transition-group>能够改变数组的排序,使用前需要先安装shufflenpm i –save lodash.shufflelet shuffle = require(’lodash.shuffle’)过滤器filterfilters串联filter可以同时串联多个filter函数。filters参数$emit父组件可以使用props把数据传递给子组件。子组件可以使用$emit触发父组件的自定义事件。 ...

February 22, 2019 · 1 min · jiezi

Python 比特币 教程 之一:创建机器人

Mixin Network 是一个免费极速的点对点加密数字货币交易系统.在本章中,你可以按教程在Mixin Messenger中创建一个bot来接收用户消息, 学到如何给机器人转比特币 或者 让机器人给你转比特币.Mixin Network的开发资源汇编课程简介创建一个接受消息的机器人机器人接受比特币并立即退还用户创建一个接受消息的机器人通过本教程,你将学会如何用Python创建一个机器人APP,让它能接受消息.Python 3 安装:本教程基于Python 3.7.2, 所以你需要安装Python 3.7.2 或 以上的版本.on macOSbrew upgradebrew install python@3on Ubuntu, 从第三方的APT源中安装.sudo apt updatesudo apt install software-properties-commonsudo add-apt-repository ppa:deadsnakes/ppa当出现下面的提示时,按"回车"继续.Press [ENTER] to continue or Ctrl-c to cancel adding it.重新更新一次apt源, 再安装python3.7, python3.7-venvsudo apt updatesudo apt install python3.7 python3.7-venvsudo ln -s /usr/bin/python3.7 /usr/bin/python3检查安装是否成功了,需要检查python3与python3-venv, 正确的提示如下:$ python3 -VPython 3.7.2root@n2:~ python3 -m venv -husage: venv [-h] [–system-site-packages] [–symlinks | –copies] [–clear] [–upgrade] [–without-pip] [–prompt PROMPT] ENV_DIR [ENV_DIR …]Creates virtual Python environments in one or more target directories.positional arguments: ENV_DIR A directory to create the environment in.optional arguments: -h, –help show this help message and exit –system-site-packages Give the virtual environment access to the system site-packages dir. –symlinks Try to use symlinks rather than copies, when symlinks are not the default for the platform. –copies Try to use copies rather than symlinks, even when symlinks are the default for the platform. –clear Delete the contents of the environment directory if it already exists, before environment creation. –upgrade Upgrade the environment directory to use this version of Python, assuming Python has been upgraded in-place. –without-pip Skips installing or upgrading pip in the virtual environment (pip is bootstrapped by default) –prompt PROMPT Provides an alternative prompt prefix for this environment.Once an environment has been created, you may wish to activate it, e.g. bysourcing an activate script in its bin directory创建 mixin_labs-python-bot 项目你首先需要创建项目目录,初始化"虚拟环境",然后安装需要的软件包.mkdir mixin_labs-python-botcd mixin_labs-python-botpython3 -m venv ./在 python3 -m venv 指令完成之后, 项目目录如下:wenewzha:mixin_labs-python-bot wenewzhang$ lsbin include lib pyvenv.cfg当"虚拟环境"创建成功后,需要激活它, 通过执行bin目录下相应的activate文件完成.wenewzha:mixin_labs-python-bot wenewzhang$ source ./bin/activate(mixin_labs-python-bot) wenewzha:mixin_labs-python-bot wenewzhang$成功激活后,可以直接执行python或pip了,这时,不再需要输入他们的完整路径了.在"虚拟环境"里安装必需的包创建一个必需包的listrequirements.txtcryptography==2.4.2pycparser==2.19pycryptodome==3.7.2PyJWT==1.7.1python-dateutil==2.7.5PyYAML==3.13requests==2.21.0websocket-client==0.54.0通过pip升级pip包本身, 并安装必需包.pip install –upgrade pippip install -r requirements.txt下载 Mixin Network的python 3的APIwget https://github.com/includeleec/mixin-python3-sdk/raw/master/mixin_ws_api.pywget https://github.com/includeleec/mixin-python3-sdk/raw/master/mixin_api.pywget https://github.com/includeleec/mixin-python3-sdk/raw/master/mixin_config.py你好,世界!创建第一个机器人APP按教程,到mixin.one创建一个APP[tutorial].生成相应的参数生成必要的参数并且记下来它们将用于mixin_config.py中.在项目目录下,创建mixin_config.py,将生成的参数,替换成你的!mixin_config.pyclient_id= ’ed882a39-0b0c-4413-bbd9-221cdeee56bf’client_secret = ‘8d7ec7b9c8261b6c7bd6309210496ca4b72bce9efc7e49be14a428ce49ff7202’pay_pin = ‘599509’pay_session_id = ‘bd53b6a4-e79a-49e5-ad04-36da518354f6’pin_token = “nVREh0/Ys9vzNFCQT2+PKcDN2OYAUSH8CidwHqDQLOCvokE7o6wtvLypjW9iks/RsnBM6N4SPF/P3bBW254YHGuDZXhitDEWOGkXs7v8BxMQxf+9454qTkMSpR9xbjAzgMXnSyHrNVoBtsc/Y+NvemB3VxPfsCOFHasiMqAa5DU=“private_key = “””—–BEGIN RSA PRIVATE KEY—–MIICXQIBAAKBgQCnaoO1SdPxggEpAIUdM/8Ll4FOqlXK7vwURHr4FFi6hnQ1I79gpZSlJdzjr24WcIuNi6kVdXVIpyzZJGXS2I72dpGs5h1jKxL8AWIUVL2axZXqTJNic4wj6GJ4gDRP2U9I9gae+S/frM6KP8TioV0OcbmrlfrwI0OElLH3363y1wIDAQABAoGAduaGLi4F8cMkMculvqzcGY57jrQZBGyg6YANWb2Rmr+9LrR5yhkvLe9rJuXEKPm7k0a6SnxGVNguWPWpv4qAVVGAJ0eb8ETXTRO20HlKmcbxfFdDtHBDV3QufNa1h3mNEsqWDNCDdAm7p/EZwfG2F9+nmeXLfip7R1I72qbK0wkCQQDiJR6NEGVwbj8HK8kRpzY1D9lPqp1ZMrma5AFYGZIb5voTxLjRpYdxQJHi7CCdE1zgqJOXvA3jj/iof7bMIJY7AkEAvYSSC5H+fUKAjyjeCTGJBBKoPDsq+aALAYLWf77sGXE9BBmhhY0liwmbj8X6/qZtQ0yEzdT/OSdiYL86CcrgFQJBALz/sMzMSzrvqJVhrqWmTdOC72d5fA+0KRKeQ9FRbZ8MJyymWKA96zhncoVoOsmMCS9pNBC4BhONm4+XTTrEcUkCQQCoDWB8Bg/G/yuExtZtDJHVHL41+rmW9UYNJvoR+TjfLrzOX/QMuyapbfGVwhdZrDaDUN0KsG9JPRVNeQR8HnwpAkACrr9cNp1H1bytHG9a6L+5cVHkRhqqEYWVO41MhgZF5bIKx5OXCJB2VwY7fjFet2KxTHGfEZt/khjFNZzVX7lN—–END RSA PRIVATE KEY—–“““需要替换的参数包括: client_id, client_secret, pay_pin, pin_token, pay_session_id, private key.创建 app-mini.py 文件, 内容如下:app-mini.pyfrom mixin_ws_api import MIXIN_WS_APIfrom mixin_api import MIXIN_APIimport mixin_configimport jsonimport timefrom io import BytesIOimport base64import gziptry: import threadexcept ImportError: import _thread as threaddef on_message(ws, message): inbuffer = BytesIO(message) f = gzip.GzipFile(mode=“rb”, fileobj=inbuffer) rdata_injson = f.read() rdata_obj = json.loads(rdata_injson) print(”——-json object begin———”) print(rdata_obj) print(”——-json object end———”) action = rdata_obj[“action”] if rdata_obj[“data”] is not None: print(“data in message:",rdata_obj[“data”]) if rdata_obj[“data”] is not None and rdata_obj[“data”][“category”] is not None: print(rdata_obj[“data”][“category”]) if action == “CREATE_MESSAGE”: data = rdata_obj[“data”] msgid = data[“message_id”] typeindata = data[“type”] categoryindata = data[“category”] userId = data[“user_id”] conversationId = data[“conversation_id”] dataindata = data[“data”] realData = base64.b64decode(dataindata) MIXIN_WS_API.replayMessage(ws, msgid) if ’error’ in rdata_obj: return if categoryindata == “PLAIN_TEXT”: realData = realData.decode(‘utf-8’) print(“dataindata”,realData) MIXIN_WS_API.sendUserText(ws, conversationId, userId, realData)if name == “main”: mixin_api = MIXIN_API(mixin_config) mixin_ws = MIXIN_WS_API(on_message=on_message) mixin_ws.run()运行 app-mini.py, 记得要先激活“虚拟环境”哦!(mixin_labs-python-bot) wenewzha:mixin_labs-python-bot wenewzhang$ python app-mini.py…如果一切正常,将会有如下提示:(mixin_labs-python-bot) wenewzha:mixin_labs-python-bot wenewzhang$ python app-mini.pyws open——-json object begin———{‘id’: ‘1c798948-30eb-11e9-a20e-20c9d08850cd’, ‘action’: ‘LIST_PENDING_MESSAGES’}——-json object end———在手机安装 Mixin Messenger,增加机器人为好友,(比如这个机器人是7000101639) 然后发送消息给它,效果如下!源代码解释WebSocket是建立在TCP基础之上的全双工通讯方式,我们需要建立一个loop循环来维持通迅。if name == “main”: mixin_api = MIXIN_API(mixin_config) mixin_ws = MIXIN_WS_API(on_message=on_message) mixin_ws.run()每接收到一个消息,需要按消息编号(message_id)给服务器回复一个"已读"的消息,避免服务器在机器人重新登入后,再次发送处理过的消息! MIXIN_WS_API.replayMessage(ws, msgid)机器人程序完整回复用户的信息if categoryindata == “PLAIN_TEXT”: realData = realData.decode(‘utf-8’) print(“dataindata”,realData) MIXIN_WS_API.sendUserText(ws, conversationId, userId, realData) Mixin Messenger支持的消息类型很多,具体可到下面链接查看: WebSocket消息类型.完成现在你的机器人APP运行起来了,开始玩吧。完整的代码在这儿 ...

February 21, 2019 · 3 min · jiezi

微信支付分开通攻略!

近期,许多朋友秀出了微信支付分,是啥?想必大家都知道,类似于蚂蚁信用分。现已在北上微信支付分开通攻略!上线,具体已上线城市不明确,预计在2019年内会在全国全部覆盖。微信支付分没有入口,如何开通?接下来是重点开通前注意:1️ 不是所有人都能开通(如果开通不了,可能你所在城市还没上线)2️ 请先看完看清开通步骤再操作,避免误操作造成经济损失!(我可不负责哦)开通步骤如下第一步 长按扫码第二步扫码可能人数较多,需要排队倒计时3分钟结束后,点击重新租借(若无需排队,跳过这一步)[图片上传中…(image-45a51c-1547255237857-8)]第三步 确认开通,并申请权益第四步 开通成功,并退出切记:请退出,退出,退出租了,你可还不了,我可不赔哦!第五步 点进钱包里,就可看到支付分入口微信支付分达到550,可以免押金使用充电宝,一些酒店也可以免押入住。据说最高分有822,快查一下你有多少分吧!快过年了,推荐两个红包活动大家可以参与一下,买点好吃的!京东无门槛红包,这个强力推荐,无门槛可叠加!邀请越多人打开,可得更多,每隔5个为大包! 云闪付红包,可线上购物或线下便利店使用!如果觉得不错!请给个「好看」并分享给你的朋友! THANDKSEnd -一个立志成大腿而每天努力奋斗的年轻人伴学习伴成长,成长之路你并不孤单!

January 12, 2019 · 1 min · jiezi

Cocos Creator 教程(1)——第一个游戏:一步两步

第一个游戏这节我们从头做一个比较有意思的小游戏——一步两步。下面是最终效果(跳一步得一分,跳两步得三分,电脑端左右键12步):一步两步写在前面这是本教程第一个游戏,所以我会讲的详细一点,但是也不能避免遗漏,所以有什么问题你可以先尝试查阅文档自己解决或者在下方留言,后面我会跟进完善。另外这个游戏并非原创,参照的是腾讯的微信小游戏《一步两步H5》,请不要直接搬过去,微信里重复的游戏太多了。创建工程选择空白项目创建工程你可以从这里下载游戏素材,然后将素材导入工程(直接拖进编辑器,或者放在工程目录)也可以从https://github.com/potato47/one-two-step下载完整代码进行参照。准备工作做完后,我会把这个游戏制作过程分为若干个小过程,让你体会一下实际的游戏制作体验。从一个场景跳转到另一个场景在res文件夹下新建一个scenes文件夹,然后在scenes里新建两个场景menu和game(右键->新建->Scene)。然后双击menu进入menu场景。在层级管理器中选中Canvas节点,在右侧属性检查器中将其设计分辨率调整为1280x720,然后将background图片拖入Canvas节点下,并为其添加Widget组件(添加组件->UI组件->Widget),使其充满画布。在Canvas下新建一个Label节点(右键->创建节点->创建渲染节点->Label),然后调整文字大小,并添加标题文字我们知道节点和组件通常是一起出现的,带有常见组件的节点在编辑器里可以直接创建,比如刚才的带有Label组件的节点和带有Sprite组件的节点,但是我们也可以新建一个空节点然后为其添加对应的组件来组装一个带有特殊功能的节点。新建节点->UI节点下有一个Button,如果你直接创建Button,你会发现它是一个带有Button组件的节点,并且有一个Label的子节点。现在我们用另一种方法创建Button:在Canvas右键新建一个空节点,然后为其添加Button组件,这时你会发现按钮并没有背景,所以我们再添加一个Sprite组件,拖入资源中的按钮背景图片,最后添加一个Label子节点给按钮添加上文字。下面我们给这个按钮添加点击事件。在资源管理器中新建src文件夹用来存放脚本,然后新建一个TypeScript脚本,名字为Menu(注意脚本组件名称区分大小写,这里建议首字母大写)。双击用VS Code打开脚本,更改如下:const { ccclass } = cc._decorator;@ccclass // 让编辑器能够识别这是一个组件export class Menu extends cc.Component { private onBtnStart() { cc.director.loadScene(‘game’); //加载game场景 }}一个类只有加上@ccclass才能被编辑器识别为脚本组件,如果你去掉@ccclass,你就不能把这个组件拖到节点上。另外可以看到代码中出现了几次cc这个东西,cc其实是Cocos的简称,在游戏中是引擎的主要命名空间,引擎代码中所有的类、函数、属性和常量都在这个命名空间中定义。很明显,我们想在点击开始按钮的时候调用onBtnStart函数,然后跳转到game场景。为了测试效果我们先打开game场景,然后放一个测试文字(将Canvas的设计分辨率也改为1280x720)。保存game场景后再回到Menu场景。Button组件点击后会发出一个事件,这个事件可以跟某个节点上的某个脚本内的某个函数绑定在一起。听着有点绕,动手做一遍就会明白这个机制。首先将Menu脚本添加为Canvas节点的组件,然后在开始按钮的Button组件里添加一个Click Event,将其指向Canvas节点下的Menu脚本里的onBtnStart函数。我们再调整一下Button的点击效果,将Button组件的Transition改为scale(伸缩效果),另外还有颜色变化和图片变化,可以自己尝试。最后点击上方的预览按钮,不出意外的话就可以在浏览器中看见预期效果。组织代码结构现在我们来编写游戏逻辑。首先我来讲一下我看到的一种现象:很多新手非常喜欢问,“看代码我都能看懂啊,但是要我自己写我就没思路啊”这时一位经验颇多的长者就会甩给他一句,“多写写就有思路了“不知道你们发现没有,这竟然是一个死循环。对于一个刚开始学习做游戏的人,首先要了解的是如何组织你的代码,这里我教给大家一个最容易入门的代码结构——单向分权结构(这是我想了足足两分钟的自认为很酷炫的一个名字)脚本分层:这个结构最重要的就是“权”这个字,我们把一个场景中使用的脚本按照“权力”大小给它们分层,权力最大的在最上层且只有一个,这个脚本里保存着它直接控制的若干个脚本的引用,被引用的脚本权力就小一级,被引用的脚本还会引用比它权力更小的脚本,依此类推。脚本互操作:上一层的脚本由于保存着下一层脚本的引用,所以可以直接操作下一层的脚本。下一层的脚本由上一层的脚本初始化,在初始化的时候会传入上一层的引用(可选),这样在需要的时候会反馈给上一层,由上一层执行更具体的操作。同层的脚本尽量不要互相操作,统一交给上层处理,同层解耦。不可避免的同层或跨层脚本操作可以使用全局事件来完成。具有通用功能的脚本抽离出来,任意层的脚本都可以直接使用。写了这么多,但你肯定没看懂,现在你可以翻到最上面再分析一下游戏的game场景,如何组织这个场景的脚本结构?首先,一个场景的根节点会挂载一个脚本,通常以场景名命名,这里就是Game。然后跳跃的人物也对应着一个脚本Player。跟Player同层的还应该有Block也就是人物踩着的地面方块。因为Player和Block之间互相影响并且我想让Game脚本更简洁,所以这里再加一个Stage(舞台)脚本来控制Player和Block。最终它们的层级关系如下:GameStagePlayerBlock上面这些都是我们的思考过程,下面我们落实到场景中。先新建几个脚本现在搭建场景,先添加一个跟menu场景一样的全屏背景然后添加一个空节点Stage,在Stage下添加一个Player节点和一个Block节点在Stage同层添加两个按钮来控制跳一步两步先添加第一个按钮,根据实际效果调整文字大小(font size)颜色(node color)和按钮的缩放倍数(scale)第二个按钮可以直接由第一个按钮复制这两个按钮显然是要放置在屏幕左下角和右下角的,但是不同屏幕大小可能导致这两个按钮的位置跑偏,所以最好的方案是给这两个按钮节点添加Widget组件,让它们跟左下角和右下角保持固定的距离,这里就不演示了,相信你可以自己完成(其实是我忘录了。。。)添加一个Label节点记录分数,系统字体有点丑,这里替换成我们自己的字体最后把脚本挂在对应的节点上。场景搭建到这里基本完成了,现在可以编写脚本了。Game作为一个统领全局的脚本,一定要控制关键的逻辑,,比如开始游戏和结束游戏,增加分数,还有一些全局的事件。Game.tsimport { Stage } from ‘./Stage’;const { ccclass, property } = cc._decorator;@ccclassexport class Game extends cc.Component { @property(Stage) private stage: Stage = null; @property(cc.Label) private scoreLabel: cc.Label = null; private score: number = 0; protected start() { this.startGame(); } public addScore(n: number) { this.score += n; this.scoreLabel.string = this.score + ‘’; } public startGame() { this.score = 0; this.scoreLabel.string = ‘0’; this.stage.init(this); } public overGame() { cc.log(‘game over’); } public restartGame() { cc.director.loadScene(‘game’); } public returnMenu() { cc.director.loadScene(‘menu’); } private onBtnOne() { this.stage.playerJump(1); } private onBtnTwo() { this.stage.playerJump(2); }}Stage作为Game直接控制的脚本,要给Game暴露出操作的接口并且保存Game的引用,当游戏状态发生改变时,通知Game处理。Stage.tsimport { Game } from ‘./Game’;import { Player } from ‘./Player’;const { ccclass, property } = cc._decorator;@ccclassexport class Stage extends cc.Component { @property(Player) private player: Player = null; private game: Game = null; public init(game: Game) { this.game = game; } public playerJump(step: number) { this.player.jump(step); }}而Player作为最底层的一个小员工,别人让你做啥你就做啥。Player.tsconst {ccclass, property} = cc._decorator;@ccclassexport class Player extends cc.Component { public jump(step: number) { if (step === 1) { cc.log(‘我跳了1步’); } else if (step === 2) { cc.log(‘我跳了2步’); } } public die() { cc.log(‘我死了’); }}之前讲了@ccclass是为了让编辑器识别这是一个组件类,可以挂在节点上,现在我们又看到了一个@property,这个是为了让一个组件的属性暴露在编辑器属性中,观察最上面的Game脚本,发现有三个成员变量,stage,scoreLabel和score,而只有前两个变量加上了@property,所以编辑器中只能看到stage和scoreLabel。@property括号里通常要填一个编辑器可以识别的类型,比如系统自带的cc.Label,cc.Node,cc.Sprite,cc.Integer,cc.Float等,也可以是用户脚本类名,比如上面的Stage和Player。回到编辑器,我们把几个脚本暴露在编辑器的变量通过拖拽的方式指向带有类型组件的节点。再把one,two两个按钮分别绑定在game里的onBtnOne,onBtnTwo两个函数上。这时我们已经有了一个简单的逻辑,点击1或2按钮,调用Game里的onBtnOne或onBtnTwo,传递给Stage调用playerJump,再传递给Player调用jump,player就会表现出跳一步还是跳两步的反应。点击预览按钮,进行测试:你可以按F12(windows)或cmd+opt+i(mac)打开chrome的开发者工具。人物跳跃动作现在我们来让Player跳起来,人物动作的实现大概可以借助以下几种方式实现:动画系统动作系统物理系统实时计算可以看到这个游戏人物动作比较简单,跳跃路径是固定的,所以我们选择用动作系统实现人物的跳跃动作。creator自带一套基于节点的动作系统,形式如node.runAction(action)。修改Player.ts,添加几个描述跳跃动作的参数,并且添加一个init函数由上层组件即Stage初始化时调用并传入所需参数。另外更改jump函数内容让Player执行jumpBy动作。Player.ts…private stepDistance: number; // 一步跳跃距离private jumpHeight: number; // 跳跃高度private jumpDuration: number; // 跳跃持续时间public canJump: boolean; // 此时是否能跳跃public init(stepDistance: number, jumpHeight: number, jumpDuration: number) { this.stepDistance = stepDistance; this.jumpHeight = jumpHeight; this.jumpDuration = jumpDuration; this.canJump = true;}public jump(step: number) { this.canJump = false; this.index += step; let jumpAction = cc.jumpBy(this.jumpDuration, cc.v2(step * this.stepDistance, 0), this.jumpHeight, 1); let finishAction = cc.callFunc(() => { this.canJump = true; }); this.node.runAction(cc.sequence(jumpAction, finishAction));}…Stage.ts…@property(cc.Integer)private stepDistance: number = 200;@property(cc.Integer)private jumpHeight: number = 100;@property(cc.Float)private jumpDuration: number = 0.3;@property(Player)private player: Player = null;private game: Game = null;public init(game: Game) { this.game = game; this.player.init(this.stepDistance, this.jumpHeight, this.jumpDuration);}public playerJump(step: number) { if (this.player.canJump) { this.player.jump(step); }}…这里要介绍一下 Cocos Creator 的动作系统,动作系统基于节点,你可以让一个节点执行一个瞬时动作或持续性的动作。比如让一个节点执行一个“3秒钟向右移动100”的动作,就可以这样写let moveAction = cc.moveBy(3, cc.v2(100, 0)); // cc.v2可以创建一个二位的点(向量),代表方向x=100,y=0this.node.runAction(moveAction);更多的动作使用可查询文档 http://docs.cocos.com/creator…回头看Player的jump方法,这里我们的意图是让Player执行一个跳跃动作,当跳跃动作完成时将this.canJump改为true,cc.CallFunc也是一个动作,这个动作可以执行你传入的一个函数。所以上面的finishAction执行的时候就可以将this.canJump改为true,cc.sequence用于将几个动作连接依次执行。可以看到jumpAction传入了很多参数,有些参数可以直接根据名字猜到,有一些可能不知道代表什么意思,这时你就要善于搜索api,另外要充分利用ts提示的功能,你可以直接按住ctrl/cmd+鼠标单击进入定义文件查看说明示例。再来看Stage,可以看到Player初始化的几个参数是由Stage传递的,并且暴露在了编辑器界面,我们可以直接在Stage的属性面板调整参数,来直观的编辑动作效果,这也是Creator编辑器的方便之处。上面的几个参数是我调整过后的,你也可以适当的修改,保存场景后预览效果。动态添加地面和移动场景显而易见,我们不可能提前设置好所有的地面(Block),而是要根据Player跳跃的时机和地点动态添加Block,这就涉及到一个新的知识点——如何用代码创建节点?每一个Block节点都是一样的,对于这样相同的节点可以抽象出一个模板,Creator里管这个模板叫做预制体(Prefab),想要一个新的节点时就可以通过复制Prefab得到。制作一个Prefab很简单,我们先在res目录下新建一个prefabs目录,然后将Block节点直接拖到目录里就可以形成一个Prefab了。你可以双击这个prefab进入其编辑模式,如果之前忘了将Block脚本挂在Block节点上,这里也可以挂在Block的Prefab上。有了Prefab后,我们就可以利用函数cc.instance来创建出一个节点。根据之前讲的组织代码原则,创建Block的职责应该交给他的上级,也就是Stage。之前编写Player代码时设置了一个index变量,用来记录Player跳到了“第几格”,根据游戏逻辑每当Player跳跃动作完成后就要有新的Block出现在前面。修改Stage如下:Stage.tsimport { Game } from ‘./Game’;import { Player } from ‘./Player’;import { Block } from ‘./Block’;const { ccclass, property } = cc._decorator;@ccclassexport class Stage extends cc.Component { @property(cc.Integer) private stepDistance: number = 200; @property(cc.Integer) private jumpHeight: number = 100; @property(cc.Float) private jumpDuration: number = 0.3; @property(Player) private player: Player = null; @property(cc.Prefab) private blockPrefab: cc.Prefab = null; // 编辑器属性引用 private lastBlock = true; // 记录上一次是否添加了Block private lastBlockX = 0; // 记录上一次添加Block的x坐标 private blockList: Array<Block>; // 记录添加的Block列表 private game: Game = null; public init(game: Game) { this.game = game; this.player.init(this.stepDistance, this.jumpHeight, this.jumpDuration); this.blockList = []; this.addBlock(cc.v2(0, 0)); for (let i = 0; i < 5; i++) { this.randomAddBlock(); } } public playerJump(step: number) { if (this.player.canJump) { this.player.jump(step); this.moveStage(step); let isDead = !this.hasBlock(this.player.index); if (isDead) { cc.log(‘die’); this.game.overGame(); } else { this.game.addScore(step === 1 ? 1 : 3); // 跳一步得一分,跳两步的三分 } } } private moveStage(step: number) { let moveAction = cc.moveBy(this.jumpDuration, cc.v2(-this.stepDistance * step, 0)); this.node.runAction(moveAction); for (let i = 0; i < step; i++) { this.randomAddBlock(); } } private randomAddBlock() { if (!this.lastBlock || Math.random() > 0.5) { this.addBlock(cc.v2(this.lastBlockX + this.stepDistance, 0)); } else { this.addBlank(); } this.lastBlockX = this.lastBlockX + this.stepDistance; } private addBlock(position: cc.Vec2) { let blockNode = cc.instantiate(this.blockPrefab); this.node.addChild(blockNode); blockNode.position = position; this.blockList.push(blockNode.getComponent(Block)); this.lastBlock = true; } private addBlank() { this.blockList.push(null); this.lastBlock = false; } private hasBlock(index: number): boolean { return this.blockList[index] !== null; }}首先我们在最上面添加了几个成员变量又来记录Block的相关信息。然后修改了playerJump方法,让player跳跃的同时执行moveStage,moveStage方法里调用了一个moveBy动作,这个动作就是把节点相对移动一段距离,这里要注意的是moveStage动作和player里的jump动作水平移动的距离绝对值和时间都是相等的,player向前跳,stage向后移动,这样两个相反的动作,就会让player始终处于屏幕中的固定位置而不会跳到屏幕外了。再看moveStage方法里会调用randomAddBlock,也就是随机添加block,随机算法要根据游戏规则推理一下:这个游戏的操作分支只有两个:1步或者是2步。所以每2个Block的间隔只能是0步或者1步。因此randomAddBlock里会判断最后一个Block是否为空,如果为空那新添加的一定不能为空。如果不为空则50%的概率随机添加或不添加Block。这样就能得到无限随机的地图了。为了激励玩家多按2步,所以设定跳1步的1分,跳2步得3分。另外Player跳几步randomAddBlock就要调用几次,这样才能保证地图与Player跳跃距离相匹配。再说一下addBlock方法,blockNode是由blockPrefab复制出来的,你必须通过addChild方法把它添加场景中的某个节点下才能让它显示出来,这里的this.node就是Stage节点。为了方便我们把lastBlockX初始值设为0,也就是水平第一个block的横坐标应该等于0,所以我们要回到编辑器调整一下stage,player,block三个节点的位置,让block和player的x都等于0,并且把Block的宽度设为180(一步的距离设为200,为了让两个相邻的Block有一点间距,要适当窄一些),最后不要忘记把BlockPrefab拖入对应的属性上。playerJump的的最后有一段判断游戏结束的逻辑,之前我们在player里设置了一个变量index,记录player当前跳到第几格,stage里也有一个数组变量blockList保存着所有格子的信息,当player跳完后判断一下落地点是否有格子就可以判断游戏是否结束。捋顺上面的逻辑后,你就可以预览一下这个看起来有点样子的游戏了地面下沉效果如果每一步都让玩家想很久,那这个游戏就没有尽头了。现在我们给它加点难度。设置的效果是:地面每隔一段时间就会下落,如果玩家没有及时跳到下一个格子就会跟着地面掉下去,为了实现这个人物和地面同时下坠的效果,我们要让Player和Block执行相同的动作,所以在Stage上新加两个变量fallDuration和fallHeight用来代表下落动作的时间和高度,然后传给Player和Block让它们执行。另外这种小游戏的难度一定是要随着时间增加而增大的,所以Block的下落时间要越来越快。下面我们来修改Block,Player,Stage三个脚本Block.tsconst { ccclass } = cc._decorator;@ccclassexport class Block extends cc.Component { public init(fallDuration: number, fallHeight: number, destroyTime: number, destroyCb: Function) { this.scheduleOnce(() => { let fallAction = cc.moveBy(fallDuration, cc.v2(0, -fallHeight)); // 下沉动作 this.node.runAction(fallAction); destroyCb(); }, destroyTime); }}这里补充了Block的init方法,传入了四个参数,分别是坠落动作的持续时间,坠落动作的高度,销毁时间,销毁的回调函数。scheduleOnce是一个一次性定时函数,存在于cc.Component里,所以你可以在脚本里直接通过this来调用这个函数,这里要实现的效果就是延迟destroyTime时间执行下落动作。Player.tsconst { ccclass } = cc._decorator;@ccclassexport class Player extends cc.Component { private stepDistance: number; // 一步跳跃距离 private jumpHeight: number; // 跳跃高度 private jumpDuration: number; // 跳跃持续时间 private fallDuration: number; // 坠落持续时间 private fallHeight: number; // 坠落高度 public canJump: boolean; // 此时是否能跳跃 public index: number; // 当前跳到第几格 public init(stepDistance: number, jumpHeight: number, jumpDuration: number, fallDuration: number, fallHeight: number) { this.stepDistance = stepDistance; this.jumpHeight = jumpHeight; this.jumpDuration = jumpDuration; this.fallDuration = fallDuration; this.fallHeight = fallHeight; this.canJump = true; this.index = 0; }… public die() { this.canJump = false; let dieAction = cc.moveBy(this.fallDuration, cc.v2(0, -this.fallHeight)); this.node.runAction(dieAction); }}首先将init里多传入两个变量fallDuration和fallHeight用来实现下落动作,然后补充die方法,这里的下落动作其实是个上面的Block里的下落动作是一样的。Stage.ts…@property(cc.Integer)private fallHeight: number = 500;@property(cc.Float)private fallDuration: number = 0.3;@property(cc.Float)private initStayDuration: number = 2; // 初始停留时间@property(cc.Float)private minStayDuration: number = 0.3; // 最小停留时间,不能再快了的那个点,不然玩家就反应不过来了@property(cc.Float)private speed: number = 0.1;private stayDuration: number; // 停留时间…public init(game: Game) { this.game = game; this.stayDuration = this.initStayDuration; this.player.init(this.stepDistance, this.jumpHeight, this.jumpDuration, this.fallDuration, this.fallHeight); this.blockList = []; this.addBlock(cc.v2(0, 0)); for (let i = 0; i < 5; i++) { this.randomAddBlock(); }}public addSpeed() { this.stayDuration -= this.speed; if (this.stayDuration <= this.minStayDuration) { this.stayDuration = this.minStayDuration; } cc.log(this.stayDuration);}public playerJump(step: number) { if (this.player.canJump) { this.player.jump(step); this.moveStage(step); let isDead = !this.hasBlock(this.player.index); if (isDead) { cc.log(‘die’); this.scheduleOnce(() => { // 这时还在空中,要等到落到地面在执行死亡动画 this.player.die(); this.game.overGame(); }, this.jumpDuration); } else { let blockIndex = this.player.index; this.blockList[blockIndex].init(this.fallDuration, this.fallHeight, this.stayDuration, () => { if (this.player.index === blockIndex) { // 如果Block下落时玩家还在上面游戏结束 this.player.die(); this.game.overGame(); } }); this.game.addScore(step === 1 ? 1 : 3); } if (this.player.index % 10 === 0) { this.addSpeed(); } }}…Player和Block下落动作都需要的fallDuration和fallHeight我们提取到Stage里,然后又添加了几个属性来计算Block存留时间。在playerJump方法里,补充了Player跳跃后的逻辑:如果Player跳空了,那么就执行死亡动画也就是下落动作,如果Player跳到Block上,那么这个Block就启动下落计时器,当Block下落时Player还没有跳走,那就和Player一起掉下去。最后增加下落速度的方式是每隔十个格子加速一次。回到编辑器,调整fallDuration,fallHeight,initStayDuration,minStayDuration,speed的值。预览游戏添加结算面板前面讲了这么多,相信你能自己拼出下面这个界面。上面挂载的OverPanel脚本如下:OverPanel.tsimport { Game } from “./Game”;const { ccclass, property } = cc._decorator;@ccclassexport class OverPanel extends cc.Component { @property(cc.Label) private scoreLabel: cc.Label = null; private game: Game; public init(game: Game) { this.game = game; } private onBtnRestart() { this.game.restartGame(); } private onBtnReturnMenu() { this.game.returnMenu(); } public show(score: number) { this.node.active = true; this.scoreLabel.string = score + ‘’; } public hide() { this.node.active = false; }}不要忘了将两个按钮绑定到对应的方法上。最后修改Game,让游戏结束时显示OverPanelGame.tsimport { Stage } from ‘./Stage’;import { OverPanel } from ‘./OverPanel’;const { ccclass, property } = cc._decorator;@ccclassexport class Game extends cc.Component { @property(Stage) private stage: Stage = null; @property(cc.Label) private scoreLabel: cc.Label = null; @property(OverPanel) private overPanel: OverPanel = null; private score: number = 0; protected start() { this.overPanel.init(this); this.overPanel.hide(); this.startGame(); } public addScore(n: number) { this.score += n; this.scoreLabel.string = this.score + ‘’; } public startGame() { this.score = 0; this.scoreLabel.string = ‘0’; this.stage.init(this); } public overGame() { this.overPanel.show(this.score); } public restartGame() { cc.director.loadScene(‘game’); } public returnMenu() { cc.director.loadScene(‘menu’); } private onBtnOne() { this.stage.playerJump(1); } private onBtnTwo() { this.stage.playerJump(2); }}将OverPanel的属性拖上去。为了不影响编辑器界面,你可以将OverPanel节点隐藏预览效果添加声音和键盘操作方式如果你玩过这个游戏,肯定知道声音才是其灵魂。既然是Player发出的声音,就挂在Player身上吧Player.tsconst { ccclass, property } = cc._decorator;@ccclassexport class Player extends cc.Component { @property({ type: cc.AudioClip }) private oneStepAudio: cc.AudioClip = null; @property({ type:cc.AudioClip }) private twoStepAudio: cc.AudioClip = null; @property({ type:cc.AudioClip }) private dieAudio: cc.AudioClip = null; … public jump(step: number) { … if (step === 1) { cc.audioEngine.play(this.oneStepAudio, false, 1); } else if (step === 2) { cc.audioEngine.play(this.twoStepAudio, false, 1); } } public die() { … cc.audioEngine.play(this.dieAudio, false, 1); }}这里你可能比较奇怪的为什么这样写@property({ type: cc.AudioClip})private oneStepAudio: cc.AudioClip = null;而不是这样写@property(cc.AudioClip)private oneStepAudio: cc.AudioClip = null;其实上面的写法才是完整写法,除了type还有displayName等参数可选,当只需要type这个参数时可以写成下面那种简写形式,但例外的是有些类型只能写完整形式,不然就会抱警告,cc.AudioClip就是其一。在电脑上点击两个按钮很难操作,所以我们添加键盘的操作方式。Game.tsimport { Stage } from ‘./Stage’;import { OverPanel } from ‘./OverPanel’;const { ccclass, property } = cc._decorator;@ccclassexport class Game extends cc.Component { … protected start() { … this.addListeners(); } … private addListeners() { cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, (event: cc.Event.EventKeyboard) => { if (event.keyCode === cc.macro.KEY.left) { this.onBtnOne(); } else if (event.keyCode === cc.macro.KEY.right) { this.onBtnTwo(); } }, this); }}在游戏初始化的时候通过cc.systemEvent注册键盘事件,按左方向键跳一步,按右方向键跳两步。至此我们的游戏就做完了。一步两步如果你有基础,这个游戏并不难,如果这是你的第一篇教程,你可能会很吃力,无论前者后者,遇到任何问题都可以在下方留言,我也会随时更新。另外不要忘了加QQ交流群哦 863758586 ...

January 7, 2019 · 6 min · jiezi

Cocos Creator 实战教程(0)——准备

Cocos Creator简介什么的,最没意思了。安装http://www.cocos.com/downloadWindows 安装过程中会询问是否安装 Visual Studio,其作用是编译 Windows 程序,我们暂时以 Web 平台开发为主,所以可以先跳过不安装,当然你非要安装我也不能拿你怎么样。注册账号如果你第一次使用 Cocos Creator,会提示你登录账号。你可以从下面的地址注册 Cocos 开发者账号。https://passport.cocos.com/au…Dashboard空白项目:自己做游戏选择这个。范例集合:官方的一些组件用法参考,有很多文档没有的内容,没事看一下。Hello World:自带一个场景,一个脚本,两张图片,可以用来做测试工程。Hello TypeScript:同上,这个为 TypeScript 脚本。Visual Studio Code如果你有偏爱的编辑器也可以继续使用,但是 VS Code 与Cocos Creator 结合的更好。安装https://code.visualstudio.com/Chrome浏览器通常是我们的调试场景,所以建议统一用Chrome。安装https://www.google.cn/chrome/吃惊地发现下载谷歌浏览器竟然不用翻墙了。。。TypeScript”我能不能用JavaScript啊?““不能。“学习TypeScript如果你没有接触过TS,也不用担心,你只要有一门语言的基础,入门别的语言其实很简单。你可以先看一下官方文档,然后跟着教程做一个游戏,遇到不会的地方搜索提问、搜索,如此循环即可。https://www.tslang.cn/docs/ho…快速预览混个脸熟。首先选择Hello TypeScript,新建一个工程。不出意外的话你就会看到这个界面序号名称功能备注1层级管理器显示场景中的节点层级关系-2场景编辑器预览场景效果-3控件库一些常用的可视化控件个人来讲基本不用,我会把这个面板隐藏掉4资源管理器存储游戏资源-5控制台输出系统和游戏信息-6属性检查器显示节点属性-当然你可以随意调整各个面板的位置,或者隐藏掉。关于资源管理器你可能还需要知道:Scene文件夹下的helloworld是一个场景文件,里面包含着一个游戏场景的相关信息,你可以双击打开它,进入对应的场景编辑界面。Script文件夹下Helloworld是一个脚本文件,里面包含着游戏逻辑,脚本通常会挂在节点上。Texture文件夹下存放着两张图片叫做贴图资源,你可以直接将其拖入场景编辑器或层级管理器使其变为场景中的一个带有Sprite组件的节点。简单介绍一下场景(Scene)、节点(Node)、组件(Component)的关系:学到后面你会发现游戏开发里的很多概念跟拍电影有些类似,游戏的场景可以简单的类比电影里的场景,场景里有角色有背景和一些“剧本”,还有对其拍摄的摄像机。节点可以简单的理解为游戏中的物体载体,这个载体有位置有大小等基本信息,可能是玩家控制的角色,可能是天空中飘着的一段云,也可能是可以点击的一个按钮。组件是游戏中最重要的一个概念,组件是赋予节点特殊能力的一个,额,一个东东。。。比如你可以在一个节点上添加Sprite组件使其显示一张图片,添加Label组件使其显示文字,添加Collider组件使其具有物理碰撞功能,还可以添加你自己写的用户脚本组件,使其具有特定的功能。下面双击helloworld场景将其打开,你就会看到一个编辑好的场景点击顶部的三角形播放按钮,即可在浏览器中看到游戏场景。你可以在1处调整预览的设备型号,在2处调整设备方向。现在再回过头来看一下场景的节点树结构。从上向下(你可以点击对应节点,在右边属性检查器查看节点属性)CanvasCanvas是每个场景的默认根节点,你不能删除,也不能移动,它在游戏运行时会根据你设定的屏幕分辨率和适配方式自动调整大小。可以看到Node下挂载的第一个组件就是Canvas组件,你可以在这里调整设计分辨率以及适配方式。Canvas下面还有一个Helloworld组件,这个其实是我们自己写的组件,对应着左边的Helloworld脚本,里面的脚步逻辑我们回头再看。Main CameraMain Camera也是每个场景都会有的,其作用是控制场景如何显示的。现阶段不用去修改它,后面我们会专门用一章来讲Camera。background先看background下面的Sprite组件,可以看到Sprite里有一个Sprite Frame属性,你可以点击它,会发现它指向的是左边资源管理器里一张白色图片。可以看出Sprite组件就是用来让节点显示图片的。再看上面的Widget组件,应该很明显可以看出它是用来对其四边的,上下左右都是0,那么就可以让这个节点铺满屏幕。你可能又发现了这个背景在场景中显示的不是白色,颜色其实是在Node属性下设置的。这里可以看出游戏中的一个物体其实是由节点和组件共同影响的。cocos跟background一样是一个可以显示图片的节点(场景中间的Cocos图标),没有Widget组件,就不会有对齐效果,你可以任意调整其位置。label这个也很明显就是一个可以显示文字的节点,你可以修改Label组件下的String属性里的值来改变其显示的文字。最后我们在回过头来看Canvas上的Helloworld组件,选中资源管理器的Helloworld脚本文件,可以在属性检查器里看到脚本内容。可以看到里面声明了两个属性:一个是label,其类型是cc.Label,label指向的就是场景中的label节点。另一个是text,其类型是string,并且默认值是‘hello’,你也可以在属性面板修改它的值。然后在start函数里将label的string改为text的值(start函数会在所有节点加载完成后自动执行)。现在我们尝试一下修改脚本里的内容,但是打开脚本之前还有几个前提操作。将下图几个选项一次点一遍。然后就可以双击脚本用 VS Code 打开了(Windows 系统默认会打开文件夹,但是 Mac 系统默认只会打开一个文件,暂时我还没找到解决办法,我通常会先打开 VS Code 然后选择工程文件夹再打开)。打开脚本后修改在start里的内容如下:start () { // init logic this.label.string = this.text; this.label.node.color = cc.Color.RED;}然后选中Canvas节点并且在右边的属性面板里更改text的值点击上方三角形运行按钮,即可看到下面效果最后补充几点常用操作操作步骤新建场景在资源管理器里右键选择新建->Scene新建节点在层级管理器右键创建节点,如果是带有图片的节点可以直接讲图片拖入场景或层级管理器中添加组件选中节点并在属性面板的最下方选择添加组件,或者直接讲用户脚本拖入属性面板脚本属性绑定将其对应类型的节点或带有组件的节点或资源拖入帮助在学习的这条道路上,一定 不孤单 是非常孤单的,首先你要学会自己寻找解决方法,途径通常有以下几种官方文档http://docs.cocos.com/creator…当你比较生疏的名词或想深入了解的概念,首先应该想到的是去文档里搜索查看一下。官方APIhttp://docs.cocos.com/creator…查找某个变量的含义,或某个函数的用法。官方论坛http://forum.cocos.com/当你自己真的解决不了的问题时,你可以去论坛发帖寻求帮助。因为你遇到的问题可能别人早就遇到过,所以发帖前一定要先搜索一下是否有类似的帖子,解决时间就是节约生命。另外,多逛论坛也是一种学习的方式。找个组织这是我建的一个QQ群,供新手学习交流863758586

January 7, 2019 · 1 min · jiezi

以太坊构建DApps系列教程(八):启动StoryDAO

在本系列关于使用以太坊构建DApps教程的第7部分中,我们展示了如何构建应用程序的前端,为我们一直在研究的这个Story故事设置和部署UI。是时候进行一些部署并编写一些最终功能了。这是使用以太坊区块链构建去中心化应用程序系列的第八部分。我们正在建设的项目名为The Neverending Story。完整的项目可以在storydao.bitfalls.com找到。它的完整代码在GitHub上 。以下是整个系列的概述:在第1部分中,我们引导大家做了两个版本的本地区块链进行开发:Ganache版本和完整的私有PoA版本。在第2部分中,我们构建并部署了TNS代币。在第3部分,我们将介绍如何编译,部署,测试和验证我们的自定义TNS代币,该代币与所有交易所兼容,可用作常规ERC20代币。在第4部分中,我们迈出了开发Story DAO的第一步,包括白名单和测试。在第5部分中,我们处理向故事Story添加内容,查看如何添加参与者从DAO购买代币的能力以及向故事中添加提交内容。在第6部分中,我们将DAO置于最终形式,添加投票,黑名单/取消黑名单,股息分配和撤销,同时投入一些额外的辅助函数以获得良好的评价标准。在第7部分中,我们将展示如何构建应用程序的前端,为我们一直在研究的这个故事story设置和部署UI。在最后一部分中,我们将介绍部署应用程序和编写一些最终功能的最后步骤。自毁程序有些东西可能会非常非常错误,并且使得整个DAO会以某种方式被破坏——无论是通过糟糕的编写代码,还是由于参与者太多而无法完成循环。(提案上的选民太多也可能破坏系统;我们实际上没有采取任何预防措施!)为了防止发生这种情况,拥有相当于“红色大按钮”可能会很有用。首先,让我们升级我们的StoryDao:function bigRedButton() onlyOwner external { active = false; withdrawToOwner(); token.unlockForAll();}然后,让我们可以在代币合约中立即解锁所有代币:/@dev unlocks the tokens of every user who ever had any tokens locked for them*/function unlockForAll() public onlyOwner { uint256 len = touchedByLock.length; for (uint256 i = 0; i < len; i++) { locked[touchedByLock[i]] = 0; }}当然,我们需要在合约中添加这个新的地址列表:address[] touchedByLock;我们需要升级我们的increaseLockedAmount函数以向此列表添加地址:/@dev _owner will be prevented from sending _amount of tokens. Anythingbeyond this amount will be spendable.*/function increaseLockedAmount(address _owner, uint256 _amount) public onlyOwner returns (uint256) { uint256 lockingAmount = locked[_owner].add(_amount); require(balanceOf(_owner) >= lockingAmount, “Locking amount must not exceed balance”); locked[_owner] = lockingAmount; touchedByLock.push(_owner); emit Locked(_owner, lockingAmount); return lockingAmount;}我们还应该更新StoryDao合约中代币所需的接口,以包含这个新函数的签名:// … function getUnlockedAmount(address _owner) view public returns (uint256); function unlockForAll() public;}使用我们之前添加的活动故事块(除非故事的active标志为真,否则无法运行某些功能),这应该可以解决问题。没有人需要在发送合约时浪费钱,每个人的代币都会被解锁。所有者没有得到人们提交的以太。取而代之的是退出功能变得可用,因此人们可以收回他们的以太,并且每个人都会得到照顾。现在我们的合约终于可以部署了。销毁程序是什么样的?有一个名为selfdestruct的函数可以销毁合约。它看起来像这样:selfdestruct(address);调用它将禁用有问题的合约,从区块链的状态中删除其代码并禁用所有功能,同时将该地址中的以太网发送到提供的地址。在我们的案例中,这不是一个好主意:我们仍然希望人们能够撤回他们的以太;我们不想从他们那里拿走它。此外,直接发送到自杀合约地址的任何以太币将永远丢失(烧毁),因为没有办法将其取回。部署合约要完全部署智能合约,我们需要执行以下操作:部署到主网将代币发送到StoryDAO地址将Token合约的所有权转让给StoryDao。我们走吧。主网部署要部署到mainnet,我们需要在truffle.js文件中添加一个新网络:mainnet: { provider: function() { return new WalletProvider( Wallet.fromPrivateKey( Buffer.from(PRIVKEY, “hex”)), “https://mainnet.infura.io/"+INFURAKEY ); }, gasPrice: w3.utils.toWei(“20”, “gwei”), network_id: “1”,},幸运的是,这非常简单。它与Rinkeby部署几乎相同;我们只需要移除gas量(让它自己计算)并改变gas价格。我们还应该将网络ID更改为1,因为这是主网ID。我们这样使用:truffle migrate –network mainnet这里有一点需要注意。如果你在先前部署的网络上进行部署(即使你刚刚将代币部署到主网上并希望稍后部署StoryDao),你可能会收到此错误:Attempting to run transaction which calls a contract function, but recipient address XXX is not a contract address之所以发生这种情况,是因为Truffle会记住部署已经部署的合约的位置,以便它可以在后续迁移中重复使用它们,从而避免重新部署。但是如果你的网络重新启动(即Ganache)或者你进行了一些不兼容的更改,可能会发生它保存的地址实际上不再包含此代码,因此会报错。你可以通过重置迁移来解决此问题:truffle migrate –network mainnet –reset将代币发送到StoryDao地址从部署过程中获取代币的地址和StoryDao的地址。然后只需使用前面描述的MEW来发送代币。如果出现gas缺失,只需增加gas限制即可。请记住:剩余的未使用的gas总是会退回来,所以不用担心会损失比交易成本更多的钱(发送代币应该低于40000gas)。将代币的所有权转让给StoryDao要转移所有权,我们需要在代币上调用transferOwnership函数。让我们将代币加载到MEW中。在Contracts屏幕中,我们输入地址和合约的ABI(从/build文件夹中获取)。然后单击Access将允许我们在菜单中访问该合约中的功能,我们从中选择transferOwnership。提示:仅包含你要调用的函数的ABI就足够了,它不必是代币的整个ABI!你可以只包括transferOwnership函数的ABI,它就没事了!然后我们选择新的所有者(已部署的StoryDao的地址)并解锁当前所有者的钱包(我们之前发送的钱包相同的钱包)。写完此更改后,我们可以检查代币合约中的只读功能owner(与transferOwnership相同的菜单)。它应该现在显示新的所有者。为了确保StoryDao地址实际上有代币,我们可以选择balanceOf函数并在_owner字段中输入StoryDao的地址,然后单击Read:事实上,StoryDao地址中有1亿个代币。提示:我们也可以在部署步骤中完成代币发送和所有权转移。尝试弄清楚如何在测试环境中。验证根据本系列的第3部分,验证DAO和Etherscan上代币的合约将对我们有很大帮助。绿色的复选标记是一条很长的路。按照该部分中的说明验证你的合约。请注意,在验证步骤中,你现在必须将优化器标记为活动,因为我们正在优化代码以实现更便宜的部署!部署到Web要部署StoryDao的Web UI,请按照“常规”Web开发世界中的说明进行操作。因为,在这种情况下,所有的都是静态代码,你甚至可以在GitHub页面或类似的东西上托管它。在这里和这里阅读一些选项。页面启动后,配置UI以使用我们从迁移步骤获得的合约地址。或者,注册代币和StoryDao的ENS名称,你可以保持Web UI静态和固定,硬编码地址,然后只更改ENS名称所指向的以太坊地址。结论DAO教程到此结束。我们希望它能帮助你认识到Solidity开发的复杂性,但我们也希望它能让事情更加清晰,让你更加好奇。一如既往,最好的学习方式就是做。实验,犯错,重启和重建。这种类型的区块链开发需求量很大,而且它越来越受欢迎,所以你有机会接触到底层。祝好运!======================================================================分享一些以太坊、EOS、比特币等区块链相关的交互式在线编程实战教程:java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。EOS教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。汇智网原创翻译,转载请标明出处。这里是原文以太坊构建DApps系列教程(八):启动StoryDAO ...

December 29, 2018 · 1 min · jiezi

npm发布包教程(五):废弃/删除

npm包发布后可以对包进行废弃或删除操作,废弃和删除的区别在于:废弃不会将包或版本从npm仓库删除,仍然可以继续下载安装,并在安装的时候会有警示删除会将包从npm彻底删除,无法被下载安装无论是废弃还是删除,都包含两个层面:版本的废弃/删除包的废弃/删除一、废弃废弃原因:版本:鼓励用户更新最新版本包:此包不再有维护的价值第一步:废弃指定版本语法:npm deprecate <pkg>[@<version>] <message>我们以yuyy-test-pkg为例:npm deprecated yuyy-test-pkg@1.1.0 ’test deprecate’执行后我们用npm view yuyy-test-pkg versions查看版本:记录的版本号并无变化。第二步:安装废弃版本切换到test-my-pkg目录下,执行:npm i yuyy-test-pkg@1.1.0运行结果: 第三步:运行index.js在test-my-pkg目录下node index.js结果:废弃的包除了安装时会有警示,并不影响使用。二、删除npm不鼓励任何形式的删除,主要因为我们发布的包可能已经被其他人引用,如果我们删除了此包,其他人在重新安装含有我们包的依赖的工程时,出现找不到包问题。基于此,npm做了相关的删除限制:删除的版本24小时后方可重发!包发布72小时之内才可删除!第一步:删除发布的包我们之前在《npm发布包教程(二):发布包》发布的包仅为演示所用,为保持npm仓库的纯净,我们都删除掉:npm unpublish yuyy-test-pkg –forcenpm unpublish @yuyy/babel –force第二步:去官网查找第二步切换到test-my-pkg目录下,先将两个包卸载:npm rm yuyy-test-pkg @yuyy/babel结果:然后再重新安装:npm i yuyy-test-pkg @yuyy/babel结果:已经删除的包无法再安装。至此,我们完成npm包的整个生命周期的演示过程,大家可以开源的道路上又多了一条很重要的道路。不过,我觉得作为一个开发者,我们有责任和义务维护每一个社区的纯净,所以在发布npm包的时候应该尽量精益求精。相关文章:1.《npm发布包教程(一):从npm说起》2.《npm发布包教程(二):发布包》3.《npm发布包教程(三):安装发布包》4.《npm发布包教程(四):迭代》5.《npm发布包教程(五):废弃/删除》

December 22, 2018 · 1 min · jiezi

npm发布包教程(四):迭代

一个npm包发布之后,我们难免会修改一些bug,或者增改一些功能,这就涉及到对npm包的迭代。本篇文章就npm迭代涉及到一些知识点进行介绍。本次演示以《npm发布包教程(二):发布包》中发布的包为基础。npm包的每次迭代都要涉及到两个方面:内容的变更版本的变更我们首先来演示内容的变更,以yuyy-test-pkg为例一、更新内容index.js变更为:module.exports = { printMsg: function () { console.log(’this message is from yuyy-test-pkg!’); console.log(’the version of this package has updated!’); }}二、更新版本在演示版本变更前,我们先来了解一下npm版本相关的知识。npm采用语义化版本,共三位,以’.’隔开,从左至右依次代表:主版本(major)、次要版本(minor)、补丁版本(patch)。例如:1.0.0major.minor.patch关于版本变更规范:变更版本号的命令:npm version <major | minor | patch>假如我们本次是次要发布,我们执行命令:npm version minor执行结果:package.json中的version也已变为1.1.0:{ “name”: “yuyy-test-pkg”, “version”: “1.1.0”, “description”: “my first npm package”, “main”: “index.js”, “scripts”: { “test”: “echo "Error: no test specified" && exit 1” }, “keywords”: [ “npm”, “packge” ], “author”: “yuyy”, “license”: “ISC”}三、发布npm publish结果:我们可以通过命令查看我们包的所有版本:npm view yuyy-test-pkg versions结果:四、安装更新(1)切换到test-my-pkg目录下npm up yuyy-pkg结果:(2)执行index.js node index.js输出结果:以上就是npm包迭代的过程,我们本次已unscoped包yuyy-test-pkg为例,对于scoped包的迭代过程没有差异。在下一篇文章《npm发布包教程(四):删除/废弃》中我们将演示npm的废弃和删除。

December 21, 2018 · 1 min · jiezi

npm发布包教程(三):安装发布包

我们在上一篇《npm发布包教程(二):发布包》中演示了如何发布npm包,npm仓库有了我们自己的包,接下来就进入到安装并使用我们自己的包的环节。第一步:初始化测试工程mkdir test-my-pkg && cd test-my-pkg npm init -y第二步:npm官网找包官网输入我们已经发布的包yuyy-test-pkg@yuyy/babel页面会有安装命令,如下图所示:第三步:安装依次执行下面的命令 npm i yuyy-test-pkg npm i @yuyy/babel此时的目录结构:test-my-pkg├── node_modules│ ├── @yuyy│ │ └── babel│ │ ├── README.md│ │ ├── index.js│ │ └── package.json│ └── yuyy-test-pkg│ ├── README.md│ ├── index.js│ └── package.json├── package-lock.json└── package.json第四步:使用(1) 建index.js index.js:let printer = require(‘yuyy-test-pkg’);let otherPrinter = require(’@yuyy/babel’);printer.printMsg();otherPrinter.printMsg();(2) 运行index.jsnode index.js执行结果:this message is from yuyy-test-pkg!this message is from @yuyy/babel!以上即为对我们自己的包引用的整个过程,值得注意的是:我们知道在Node环境中是通过CommonJS的风格管理模块的,所以在第四步引用模块的时候使用的是require()。关于require()的原理,阮一峰老师的《require()源码解读》中有详细介绍,不再赘述,仅将require()的内部原理摘抄整理如下,以伪代码的形式呈现:Node中执行:require(X)解析过程:if(X 是Node内部模块){ return X}else if(X 带路径,以 ‘/‘、‘./‘、’../‘开头){ resolveModule(X)}else if(X 不带路径){ /当前工程/node_modules 执行 resolveModule(X) ./当前工程 node_modules 执行 resolveModule(X) ../当前工程 node_modules 执行 resolveModule(X) . . .}else { return ’not found’}function resolveModule(X){ absolutePath = X的绝对路径(根据X所在的父模块可知) if(X 是文件){ return absolutePath/X || absolutePath/X.js || absolutePath/X.json || absolutePath/X.node; }else if(X 是目录){ return absolutePath/X/package.json(main字段) || absolutePath/X/index.js || absolutePath/X/index.json || absolutePath/X/index.node }}我们将在下一篇文章《npm发布包教程(三):npm包迭代》中演示对已经发布过的包如何进行迭代,包括内容的迭代和版本的迭代。 ...

December 21, 2018 · 1 min · jiezi

npm发布包教程(二):发布包

上一篇文章《npm发布包教程(一):从npm说起》中我们介绍了npm相关的一些知识,旨在让大家对npm有一些深入的理解,这一篇我们正式开始演示发布过程。一、准备工作在正式开始演示前,我们还需要做两项准备工作:1.注册npm账户注册地址全名:邮箱:用户名:重要!发布scoped包时会用到密码:2.全局安装nrmnpm i nrm -gnrm是npm仓库管理的软件,可用于npm仓库的快速切换nrm 常用命令: nrm //展示nrm可用命令 nrm ls //列出已经配置的所有仓库 nrm test //测试所有仓库的响应时间 nrm add <registry> <url> //新增仓库 nrm use <registry> //切换仓库二、发布包开始演示前做两个简短说明:(1)npm官方建议规范的包至少包含:package.json(包的基本信息)README.md(文档)index.js (入口文件)后续的演示都遵循此规范。(2)本次仅演示个人账户的包发布,包括一个unscoped包和一个scoped的包。团体账户下的包发布流程和个人账户差别不大,在此不做展开。1.发布unscoped包yuyy-test-pkg第一步:创建项目(1)创建工程文件夹mkdir yuyy-test-pkg && cd yuyy-test-pkg(2)创建package.json npm init按照提示一步步完善即可,注意:本次演示的包的入口文件是index.js,请务必确保package.json中字段main对应的值是“index.js”。最终结果:{ “name”: “yuyy-test-pkg”, “version”: “1.0.0”, “description”: “my first npm package”, “main”: “index.js”, “scripts”: { “test”: “echo "Error: no test specified" && exit 1” }, “keywords”: [ “npm”, “packge” ], “author”: “yuyy”, “license”: “ISC”}(3)创建README.md内容:### yuyy-test-pkgThis is my first npm package!It is just for learning.(4)创建index.js内容:module.exports = { printMsg: function () { console.log(’this message is from yuyy-test-pkg!’); }}最终的目录结构:└── yuyy-test-pkg ├── README.md ├── index.js └── package.json第二步:发布npm publish可能报的错:(1)未登录npm ERR! code ENEEDAUTHnpm ERR! need auth auth required for publishingnpm ERR! need auth You need to authorize this machine using npm adduser解决办法:npm adduser输入:用户名(忘记的话,去npm网站查看:头像 > Profile Settings)密码邮箱(2)仓库地址不对npm ERR! code E409npm ERR! Registry returned 409 for PUT on http://r.cnpmjs.org/-/user/or...:yuyy: conflict原因:通过nrm ls 命令查看我此时的仓库地址为cnpm,而不是npm解决办法:用nrm切换到npm仓库,执行命令nrm use npm以上问题解决后再次执行发布命令npm publish,发布成功.第三步:去npm 官网搜索有可能有延迟,不能立马看不到。2.发布scoped包@yuyy/babel第一步:创建项目(1)创建工程文件夹mkdir babel && cd babel(2)创建package.json npm init按提示操作,最终结果:{ “name”: “babel”, “version”: “1.0.0”, “description”: “my scoped test package”, “main”: “index.js”, “scripts”: { “test”: “echo "Error: no test specified" && exit 1” }, “keywords”: [ “npm”, “package” ], “author”: “yuyy”, “license”: “ISC”}(3)创建README.md内容:### @yuyy/babelThis is my scoped npm package!It is just for learn.(4)创建index.js内容:module.exports = { printMsg: function () { console.log(’this message is from @yuyy/babel!’); }}最终的目录结构:└── babel ├── README.md ├── index.js └── package.json第二步:发布npm publish报错:没有发布权限npm ERR! publish Failed PUT 401npm ERR! code E401npm ERR! This package requires that publishers enable TFA and provide an OTP to publish. For more info, visit: https://go.npm.me/2fa-guide : babel原因:已经存在babel包,而我又不是babel的发布者解决:包名和域名差不多,先到先得,如果我非要发布一个叫babel的包,只能给它加作用域放到我的命名空间下第三步:加作用域npm init –scope=@yuyy -y@符号后面的是你注册npm账户时的username,如果不记得可以通过npm whoami查询。上面的命令其实是在重新生成package.json,只是会给包增加了作用域,执行完后package.json现在的内容:{ “name”: “@yuyy/babel”, “version”: “1.0.0”, “description”: “my scoped test package”, “main”: “index.js”, “scripts”: { “test”: “echo "Error: no test specified" && exit 1” }, “keywords”: [ “npm”, “package” ], “author”: “yuyy”, “license”: “ISC”}唯一的变化是name字段由原来的babel变成了@yuyy/babel。第四步:再次发布npm publish报错:npm ERR! publish Failed PUT 402npm ERR! code E402npm ERR! You must sign up for private packages : @yuyy/babel原因:npm publish 命令执行,默认是进行私有发布,参见官网publish命令上一篇文章最后提到过scoped的包私有发布时需要收费解决:如果不想花钱,那只能将包面向公共发布,这也符合npm鼓励开源的精神,这一点和GitHub创建仓库类似。第五步:公共发布npm publish –access public执行结果:值得注意的一点:我们的项目名是babel,最终发布的包名是@yuyy/babel,可见发布的包名可以和项目名不一致,包名取决于package.json中的name字段。第六步:npm官网搜索至此,我们完成了npm包发布的全部过程,一个unscoped包:yuyy-test-pkg,另一个scoped包:@yuyy/babel,也包括过程中可能遇到的问题。发布完我们自己的包之后,我们会在下一篇文章中介绍安装自己的包和涉及到的一些引用模块相关的知识,以及后续文章中介绍如何对发布过的包进行升级和废弃等。 ...

December 20, 2018 · 2 min · jiezi

npm发布包教程(一):从npm说起

作为一个前端,每个人应该对npm install这个命令应该非常熟悉了,尤其是对这个命令执行过程中命令窗口疯狂输出肯定印象深刻。我发现有的同学对安装包轻车熟路,但对包从哪里来的以及如何发布一个npm并不是很了解,基于此,在团队内部做了一次分享,将分享过程整理如下,希望对每一个想发布自己的包但又不知从何开始的同学有所帮助。由于发布包涉及到发布、安装、更新、删除/废弃等阶段,写在一篇文章中篇幅过长,决定拆开做成一个系列。今天第一篇首先介绍一下npm相关的一些知识。npm(node package manager)是一个辅助前端开发的包管理工具包括:网站:找包、注册用户命令行:程序员与npm交互的主要形式仓库:最大的JavaScript软件库管理对象:包(package)管理方式:增(发布:npm publish;安装:npm i)删(废弃:npm deprecate;卸载:npm rm)改(更新:npm up)查(搜索:npm s)npm中涉及到的主体主要有两个:package和module,定义如下:package:含有package.json描述文件并发布到npm仓库的文件或者文件夹module:在node_modules中,可以被Node.js的require()方法加载的任何文件或文件夹可以这样理解:一个JavaScript软件,从本地发布到npm仓库时是package,从npm仓库下载到本地时就变成了module另外,基于以上,可以看出package和module的关系:module不一定是package(比如node内置模块),package一定是module含package.json文件的module一定是package除了以上概念外,再分别看下两个主体中的细节部分:package(包)主要有两个重要的属性:1.Scope(作用域,范围)一旦注册个人或者团体账户,就获得了与个人或者团体名相匹配的scope,可以用这个scope作为包的命名空间,例如@yuyy、@58。分类:unscoped:例如babelscopeduser: 例如@yuyy/babelorg:@babel/parser作用:为你自己发布的包提供命名空间,防止与他人的包名冲突2.Accessibility(可访问性)属性值有:private:私有,仅作者本人或团队成员可见public:公有,所有人可见此属性和github创建仓库时设定访问性的策略一致:公有,所有人可见,免费;私有,仅自己可见,收费。以上两个属性之间的关系如下:需要说明的几点:个人账户(User)可以创建和管理Unscoped的package;团队账户(Org)相互只能管理Scoped的packageUnscoped总是publicPrivate的package总是ScopedScoped的package默认Private,但需要付费,可以通过命令行改变其属性module(模块)下载到本地的module主要是用于在node环境被引用,为了能被Node.js的require()方法加载,module必须是下列情况之一:包含package.json,且package.json中有main字段的文件夹含有index.js的文件夹JavaScript文件以上都是一些npm相关的知识,在下一篇《npm发布包教程(二):发布包》中,我们开始演示发布npm包的实际操作过程。

December 20, 2018 · 1 min · jiezi