Loryfeng's blog

mark something.


  • 首页

  • 标签

  • 分类

  • 归档

  • 关于

  • 搜索

php入门

发表于 2018-04-08 | 分类于 php | | 阅读次数:

php入门

php是什么

PHP(Hypertext Preprocessor)是一种创建动态交互性站点的强有力的服务器端开源脚本语言。

php特点

  1. PHP 独特的语法混合了 C、Java、Perl 以及 PHP 自创新的语法。
  2. PHP可以比CGI或者Perl更快速的执行动态网页——动态页面方面,与其他的编程语言相比,
    PHP是将程序嵌入到HTML文档中去执行,执行效率比完全生成htmL标记的CGI要高许多;
    PHP具有非常强大的功能,所有的CGI的功能PHP都能实现。
  3. PHP支持几乎所有流行的数据库以及操作系统。
  4. 最重要的是PHP可以用C、C++进行程序的扩展!

php优势

  1. 开放源代码
    所有的PHP源代码事实上都可以得到。

  2. 免费性
    和其它技术相比,PHP本身免费且是开源代码。

  3. 快捷性
    程序开发快,运行快,技术本身学习快。嵌入于HTML:因为PHP可以被嵌入于HTML语言,它相对于其他语言。编辑简单,实用性强,更适合初学者。

  4. 跨平台性强
    由于PHP是运行在服务器端的脚本,可以运行在UNIX、LINUX、WINDOWS、Mac OS、Android等平台。

  5. 效率高
    PHP消耗相当少的系统资源。

  6. 图像处理
    用PHP动态创建图像,PHP图像处理默认使用GD2。且也可以配置为使用image magick进行图像处理。

  7. 面向对象
    在php4,php5 中,面向对象方面都有了很大的改进,php完全可以用来开发大型商业程序。

  8. 专业专注
    PHP支持脚本语言为主,同为类C语言。

开发工具

集成开发环境是一种集成了软件开发过程中所需主要工具的集成开发环境,其功能包括但不仅限于代码高亮、代码补全、调试、构建、版本控制等。一些常见的PHP IDEs如下:

  • Zend Studio:商业版,Zend官方出品,基于eclipse
  • Eclipse with PDT:免费
  • PHP Storm:商业版

php安装

使用php进行web系统开发,需要:

  • 安装 Web 服务器
  • 安装 PHP
  • 安装数据库,比如 MySQL

官方 PHP 网站(PHP.net)有 PHP 的安装说明: http://php.net/manual/zh/install.php

php依赖管理

对于现代语言而言,包管理器基本上是标配。Java 有 Maven,Python 有 pip,Ruby 有 gem,Nodejs 有 npm。而Composer,是PHP依赖管理的利器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1、安装Composer:
$ curl -sS https://getcomposer.org/installer | php
$ mv composer.phar /usr/local/bin/composer

2、声明依赖:
在项目目录下创建一个 composer.json 文件,指明依赖,比如,你的项目依赖 monolog:
{
"require": {
"monolog/monolog": "1.2.*"
}
}

3、安装依赖:
composer install

4、自动加载:
Composer 提供了自动加载的特性,只需在你的代码的初始化部分中加入下面一行:
require 'vendor/autoload.php';

php插件安装

Linux系统中,PHP安装成功后,在bin目录下会生成一个名叫phpize的可执行脚本,这个脚本的用途是动态安装php扩展模块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
注:以PHP安装mysql.so扩展为例

1、进入php源码的ext/mysql目录
cd /usr/local/src/php/ext/mysql/

2、运行phpize,在该目录下生成一个configure文件(php安装目录:/usr/local/php/)
/usr/local/php/bin/phpize

3、运行configure,指明php-config文件位置(/usr/local/php/bin/php-config)和mysql安装目录(/usr/local/mysql/)
./configure --with-php-config=/usr/local/php/bin/php-config --with-mysql=/usr/local/mysql/

4、编译安装,生成mysql.so
make && make install

5、修改php.ini文件,添加mysql.so扩展配置,保存退出
extension=mysql.so

6、重启php-fpm
service php-fpm restart

php基础语法

  • 基础php语法:

PHP 脚本可放置于文档中的任何位置。
PHP 脚本以 <?php 开头,以 ?> 结尾

1
2
3
<?php
// 此处是 PHP 代码
?>
  • php中的注释:
1
2
3
4
5
6
7
8
9
// 这是单行注释

# 这也是单行注释

/*
...
多行注释块
...
*/
  • php大小写敏感

在 PHP 中,所有用户定义的函数、类和关键词(例如 if、else、echo 等等)都对大小写不敏感。
不过在 PHP 中,所有变量都对大小写敏感。

  • php变量

PHP 是一门类型松散的语言,PHP根据它的值,自动把变量转换为正确的数据类型。

1
2
3
4
5
6
PHP 变量规则:
变量以 $ 符号开头,其后是变量的名称
变量名称必须以字母或下划线开头
变量名称不能以数字开头
变量名称只能包含字母数字字符和下划线(A-z、0-9 以及 _)
变量名称对大小写敏感($y 与 $Y 是两个不同的变量)
  • php数据类型

字符串、整数、浮点数、逻辑、数组、对象、NULL。

  • php字符串函数
1
2
3
4
5
6
7
8
9
10
11
strlen() //返回字符串的长度
strpos() //用于检索字符串内指定的字符或文本
explode() //把字符串打散为数组
implode() //返回由数组元素组合成的字符串
md5() //计算字符串的 MD5 散列
str_replace() // 替换字符串中的一些字符
str_split() //把字符串分割到数组中
strcmp() // 比较两个字符串(对大小写敏感)
strstr() //查找字符串在另一字符串中的第一次出现(对大小写敏感)
trim() // 移除字符串两侧的空白字符和其他字符
...
  • php常量

常量是单个值的标识符(名称)。在脚本中无法改变该值。
有效的常量名以字符或下划线开头(常量名称前面没有 $ 符号)。

1
2
3
4
<?php
define("GREETING", "Welcome to W3School.com.cn!");
echo GREETING;
?>
  • php运算符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
算术运算符:
+ - * / %

赋值运算符:
= += -= *= /= %

字符串运算符:
. .=

递增/递减运算符:
++$x $x++ --$x $x--

比较运算符:
== === != <> !== > < >= <=

逻辑运算符:
and or xor && || !
  • php条件语句

在您编写代码时,经常会希望为不同的决定执行不同的动作。您可以在代码中使用条件语句来实现这一点。
在 PHP 中,我们可以使用以下条件语句:

1
2
3
4
if 语句 - 如果指定条件为真,则执行代码
if...else 语句 - 如果条件为 true,则执行代码;如果条件为 false,则执行另一端代码
if...elseif....else 语句 - 选择若干段代码块之一来执行
switch 语句 - 语句多个代码块之一来执行
  • php循环语句

在您编写代码时,经常需要反复运行同一代码块。我们可以使用循环来执行这样的任务,而不是在脚本中添加若干几乎相等的代码行。

1
2
3
4
5
6
7
while - 只要指定条件为真,则循环代码块

do...while - 先执行一次代码块,然后只要指定条件为真则重复循环

for - 循环代码块指定次数

foreach - 遍历数组中的每个元素并循环代码块
  • php函数

除了内建的 PHP 函数,我们可以创建我们自己的函数。
用户定义的函数声明以”function” 开头,可以通过参数向函数传递信息。
参数被定义在函数名之后,括号内部。您可以添加任意多参数,只要用逗号隔开即可。

1
2
3
4
function sum($x,$y) {
$z=$x+$y;
return $z;
}
  • php数组

数组能够在单独的变量名中存储一个或多个值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
//普通数组
$cars=array("Volvo","BMW","SAAB");
$arrlength=count($cars);

for($x=0;$x<$arrlength;$x++) {
echo $cars[$x];
echo "<br>";
}

//关联数组
$age=array("Bill"=>"35","Steve"=>"37","Peter"=>"43");

foreach($age as $x=>$x_value) {
echo "Key=" . $x . ", Value=" . $x_value;
echo "<br>";
}
?>
  • php超级全局变量

PHP中预定义了几个超级全局变量(superglobals),这意味着它们在一个脚本的全部作用域中都可用。你不需要特别说明,就可以在函数及类中使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$GLOBALS //$GLOBALS 是PHP的一个超级全局变量组,包含了全部变量的全局组合数组。变量的名字就是数组的键

$_SERVER //$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组

$_REQUEST //$_REQUEST 用于收集HTML表单提交的数据

$_POST //$_POST 被广泛应用于收集表单数据,在HTML form标签的指定该属性:"method="post"

$_GET //$_GET 同样被广泛应用于收集表单数据,在HTML form标签的指定该属性:"method="get"

$_FILES //通过使用 PHP 的全局数组 $_FILES,你可以从客户计算机向远程服务器上传文件

$_ENV //通过环境方式传递给当前脚本的变量的数组

$_COOKIE //$_COOKIE 变量用于取回 cookie 的值

$_SESSION //存储和取回 session 变量
  • php魔术变量

PHP 向它运行的任何脚本提供了大量的预定义常量。魔术常量它们的值随着它们在代码中的位置改变而改变。

1
2
3
4
5
6
7
__LINE__ //文件中的当前行号。
__FILE__ //文件的完整路径和文件名
__DIR__ //文件所在的目录
__FUNCTION__ //函数名称
__CLASS__ //函数名称
__METHOD__ //类的方法名
__NAMESPACE__ //当前命名空间的名称
  • php命名空间

PHP 命名空间可以解决以下两类问题:
1、用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
2、为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

1
2
3
4
<?php  
namespace MyProject1;
// MyProject1 命名空间中的PHP代码
?>
  • php面向对象

面向对象关键知识点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
类:定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。

对象:是类的实例。

成员变量:定义在类内部的变量。该变量的值对外是不可见的,但是可以通过成员函数访问,在类被实例化为对象后,该变量即可称为对象的属性。

成员函数:定义在类的内部,可用于访问对象的数据。

继承:继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。

父类:一个类被其他类继承,可将该类称为父类,或基类,或超类。

子类:一个类继承其他类称为子类,也可称为派生类。

多态:多态性是指相同的函数或方法可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。

重载:简单说,就是函数或者方法有同样的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。

抽象性:抽象性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。

封装:封装是指将现实世界中存在的某个客体的属性与行为绑定在一起,并放置在一个逻辑单元内。

构造函数:主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。

析构函数:析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做"清理善后" 的工作(例如在建立对象时用new开辟了一片内存空间,应在退出前在析构函数中用delete释放)。

PHP 对属性或方法的访问控制,是通过在前面添加关键字 public(公有),protected(受保护)或 private(私有)来实现的。
public(公有):公有的类成员可以在任何地方被访问。
protected(受保护):受保护的类成员则可以被其自身以及其子类和父类访问。
private(私有):私有的类成员则只能被其定义所在的类访问。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php 
class Site {
/* 成员变量 */
var $url;
var $title;

/* 成员函数 */
function setUrl($par){
$this->url = $par;
}

function getUrl(){
echo $this->url . PHP_EOL;
}

function setTitle($par){
$this->title = $par;
}

function getTitle(){
echo $this->title . PHP_EOL;
}
}

$google = new Site;
$google->setTitle( "Google 搜索" );
$google->setUrl( 'www.google.com' );
$google->getTitle();
$google->getUrl();
?>

php入门实践

1
2
3
4
使用LNMP(linux+nginx+mysql+php)完成demo的开发。
1、使用CodeIgniter框架进行开发;
2、操作mysql数据库;
3、使用nginx作为web服务器;

相关学习资料

php官网
PHP入门教程
PHPChina开发者社区
PHP Composer:PHP依赖管理工具
Laravel官网:最流行的PHP开发框架
ThinkPHP:中文最佳实践PHP开源框架
CodeIgniter:一个小巧但功能强大的PHP框架
Yii:基于组件,用于开发大型Web应用的高性能PHP框架
Swoole:php的异步、并行、高性能网络通信引擎
Workerman:一款纯PHP开发的开源的PHP socket服务器框架

Kubernetes入门

发表于 2018-04-08 | 分类于 kubernetes | | 阅读次数:

Kubernetes分享

简介

容器编排引擎
基于容器的应用一般会采用微服务架构。在这种架构下,应用被划分为不同的组件,并以服务的形式运行在各自的容器中,通过 API 对外提供服务。为了保证应用的高可用,每个组件都可能会运行多个相同的容器。这些容器会组成集群,集群中的容器会根据业务需要被动态地创建、迁移和销毁。这样一个基于微服务架构的应用系统实际上是一个动态的可伸缩的系统。这对部署环境提出了新的要求,我们需要有一种高效的方法来管理容器集群。而这,就是容器编排引擎要干的工作。
所谓编排,通常包括容器管理、调度、集群定义和服务发现等。通过容器编排引擎,容器被有机的组合成微服务应用,实现业务需求。

Kubernetes提供应用部署、维护、 扩展机制等功能,利用Kubernetes能方便地管理跨机器运行容器化的应用。

K8s架构图

K8S架构

[^_^]:
这是可爱的注释

  • Master节点

    • kube-apiserver
      API Server作为kubernetes系统的入口,封装了核心对象的增删改查操作,以RESTful接口方式提供给外部客户和内部组件调用。它维护的REST对象将持久化到etcd。

    • kube-scheduler
      Scheduler 负责决定将 Pod 放在哪个 Node 上运行。Scheduler 在调度时会充分考虑 Cluster 的拓扑结构,当前各个节点的负载,以及应用对高可用、性能、数据亲和性的需求。这部分工作分出来变成一个组件,意味着可以很方便地替换成其他的调度器。

    • kube-controller-manager
      Controller Manager 负责管理 Cluster 各种资源,保证资源处于预期的状态。Controller Manager 由多种 controller 组成,包括 replication controller、endpoints controller、namespace controller、serviceaccounts controller 等。

    • etcd
      etcd 负责保存 Kubernetes Cluster 的配置信息和各种资源的状态信息。当数据发生变化时,etcd 会快速地通知 Kubernetes 相关组件。

    • Pod网络方案
      Pod 要能够相互通信,Kubernetes Cluster 必须部署 Pod 网络,flannel 是其中一个可选方案。

  • Node节点

    • kubelet
      负责管控docker容器,如启动/停止、监控运行状态等。它会定期从etcd获取分配到本机的pod,并根据pod信息启动或停止相应的容器。同时,它也会接收apiserver的HTTP请求,汇报pod的运行状态。

    • kube-proxy
      负责为pod提供代理。它会定期从etcd获取所有的service,并根据service信息创建代理。当某个客户pod要访问其他pod时,访问请求会经过本机proxy做转发。如果有多个副本,kube-proxy 会实现负载均衡。

搭建k8s集群

  • 使用Minikube快速完成集群搭建
    https://kubernetes.io/docs/tutorials/kubernetes-basics/

  • k8s集群搭建
    https://blog.csdn.net/running_free/article/details/78388948

k8s核心概念

  • Cluster
    Cluster 是计算、存储和网络资源的集合,Kubernetes 利用这些资源运行各种基于容器的应用。

  • Master
    Master 是 Cluster 的大脑,它的主要职责是调度,即决定将应用放在哪里运行。Master 运行 Linux 操作系统,可以是物理机或者虚拟机。为了实现高可用,可以运行多个 Master。

  • Node
    Node 的职责是运行容器应用。Node 由 Master 管理,Node 负责监控并汇报容器的状态,并根据 Master 的要求管理容器的生命周期。Node 运行在 Linux 操作系统,可以是物理机或者是虚拟机。

  • Pod
    Pod 是 Kubernetes 的最小工作单元。每个 Pod 包含一个或多个容器。Pod 中的容器会作为一个整体被 Master 调度到一个 Node 上运行。
    Kubernetes 引入 Pod 主要基于下面两个目的:
    1、可管理性。
    有些容器天生就是需要紧密联系,一起工作。Pod 提供了比容器更高层次的抽象,将它们封装到一个部署单元中。Kubernetes 以 Pod 为最小单位进行调度、扩展、共享资源、管理生命周期。
    2、通信和资源共享。
    Pod 中的所有容器使用同一个网络 namespace,即相同的 IP 地址和 Port 空间。它们可以直接用 localhost 通信。同样的,这些容器可以共享存储,当 Kubernetes 挂载 volume 到 Pod,本质上是将 volume 挂载到 Pod 中的每一个容器。

  • Controller
    Kubernetes 通常不会直接创建 Pod,而是通过 Controller 来管理 Pod 的。Controller 中定义了 Pod 的部署特性,比如有几个副本,在什么样的 Node 上运行等。为了满足不同的业务场景,Kubernetes 提供了多种 Controller,包括 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等。

  • Service
    Kubernetes Service 定义了外界访问一组特定 Pod 的方式。Service 有自己的 IP 和端口,Service 为 Pod 提供了负载均衡。可以通过nodeport实现对外提供服务。

  • Namespace
    Namespace 可以将一个物理的 Cluster 逻辑上划分成多个虚拟 Cluster,每个 Cluster 就是一个 Namespace。不同 Namespace 里的资源是完全隔离的。使用namespace来组织kubernetes的各种对象,可以实现对用户的分组,即“多租户”管理。对不同的租户还可以进行单独的资源配额设备和管理,使得整个集群配置非常灵活、方便。

  • Label
    label是kubernetes系统中的一个核心概念。Label以key/value键值对的形式附加到各种对象上,如pod、service、RC、Node等。Label定义了这些对象的可识别属性,用来对它们进行管理和选择。Label可以在创建对象时附加到对象上,也可以在对象创建后通过API进行管理。

  • Volume
    volume是pod中能够被多个容器访问的共享目录。Kubernetes的volume概念与docker的volume比较类似,但并不完全相同。Kubernetes中的volume与pod生命周期相同,但与容器的生命周期不相关。当容器终止或重启时,volume中的数据也不会丢失。另外,kubernetes支持多种类型的volume,并且一个pod可以同时使用任意多个volume。

  • Annotation
    Annotation则是用户任意定义的“附加”信息,以便于外部工具进行查找。

  • 健康检查
    pod通过两类探针来检查容器的健康状态。一个是LivenessProbe探针,用于判断容器是否健康,告诉kubelet一个容器什么时候处于不健康的状态。如果LivenessProbe探针探测到容器不健康,则kubelet将删除容器,并根据容器的重启策略做相应的处理。如果一个容器不包含LivenessProbe探针,那么kubelet认为该容器的LivenessProbe探针返回的值永远是“success”.另一类是ReadinessProbe探针,用于判断容器是否启动完成,且准备接收请求。如果ReadinessProbe探针检测到失败,则pod的状态将被修改。Endpoint controller将从service的endpoint中删除包含该容器所在pod的IP地址的endpoint条目。

Controller组件

  • Replication Controller
    Replication Controller的核心作用是确保在任何时间集群中一个RC所关联的pod都保持一定数量的pod副本处于正常运行状态。

  • Node Controller
    Node Controller负责发现、管理和监控集群中的各个node节点。

  • ResourceQuota Controller
    作为容器集群的管理平台, kubernetes也提供了资源配额管理这一高级功能,资源配额管理确保指定的对象在任何时候都不会超量占用系统资源,避免了由于某些业务进程的设计或实现的缺陷导致整个系统运行紊乱甚至意外宕机,对整个集群的平稳运行和稳定性有非常重要的作用。

目前kubernetes支持三个层次的资源配额管理:
(1)容器级别,可以对CPU和内存的资源配额管理。
(2)pod级别,可以对pod内所有容器的可用资源进行限制。
(3)namespace级别,为namespace(可以用于多租户)级别的资源限制,包括:pod数量、replication Controller数量、service数量、ResourceQuota数量、secret数量、可持有的PV(persistent volume)数量。
kubernetes的配额管理是通过准入机制(admission control)来实现的,与配额相关的两种准入控制器是LimitRanger和ResoureQuota,其中LimitRanger作用于pod和container上,ResourceQuota则作用于namespace上。

  • Namespace Controller
    负责管理集群namespace资源。

  • Token Controller
    token controller对象监听Service Account的创建、修改和删除事件,并根据事件的不同做不同的处理。

  • Service Controller
    Kubernetes service是一个定义pod集合的抽象,或者被访问都看作一个访问策略,有时也被称为微服务。

k8s核心功能

  • 应用部署
1
2
3
kubectl run kubernetes-bootcamp \
--image=docker.io/jocatalin/kubernetes-bootcamp:v1 \
--port=8080
  • 应用访问
1
2
3
kubectl expose deployment/kubernetes-bootcamp \
--type="NodePort" \
--port 8080
  • 应用扩缩容
1
kubectl scale deployments/kubernetes-bootcamp --replicas=3
  • 滚动更新
1
kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2
  • 应用回滚
1
kubectl rollout undo deployments/kubernetes-bootcamp
  • 弹性伸缩
1
kubectl autoscale deployment sqm-deploy --cpu-percent=20 --min=1 --max=5

Kubernetes API

Kuberbetes API是集群系统中重要组成部分,k8s中各种资源的数据通过该API接口被提交到后端的持久化存储中,Kubernetes集群中的各部件之间通过该API接口实现解耦合,同时K8s集群中一个重要且便捷的管理工具kubctl也是通过访问该API接口实现强大的管理功能的。

Api文档地址

官方支持的Kubernetes客户端库:
Go语言
Python语言

安全机制

  • Authentication认证
    • CA
    • Token
    • HTTP Base
  • Authorization授权(作用于Api Server主要端口的所有HTTP访问)
    • AlwaysDeny
    • AlwaysAllow
    • ABAC
    • RBAC
    • …
  • Admission Control准入控制(用于拦截所有经过认证和鉴权后访问Api Server请求的插件)
    • AlwaysAdmin
    • AlwaysDeny
    • ServiceAccount
    • ResourceQuota
    • LimitRanger
    • SecurityContexDeny
    • …

资源配额管理

需要保证kube-apiserver中的–admission_control参数中包含“LimitRanger,ResourceQuota”;

  • 指定容器配额

通过Pod或ReplicationController的定义文件中设定resources属性即可为某个容器指定配额(仅支持CPU和内存)。

  • 全局默认配额

通过创建LimitRange对象来定义一个全局默认配额模板。这个默认配额模版会加载到集群中的每个Pod及容器上。LimitRange可以同时在Pod和Container两个级别上进行资源配置。可关联到指定的Namespace上。

  • 多租户配额管理

不同的租户对应Namespace加载对应的ResourceQuota配置即可。

读懂YAML文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
template:
metadata:
labels:
app: web_server
spec:
containers:
- name: nginx
image: nginx:1.7.9
port:
- containerPort: 8080
volumeMounts:
- name: "persistent-storage"
mountPath: "/data"
volumes:
- name: "persistent-storage"
hostPath:
path: "/data"
  1. apiVersion指定当前配置格式的版本;
  2. kind指定要创建的资源类型;
  3. metadata指该资源的元数据信息,name是必须的元数据项;
  4. spec指定该Deployment规格说明;
  5. replicas指明副本数量,默认为1;
  6. template定义Pod模板;
  7. metadata定义Pod元数据,至少要定义一个label;
  8. spec描述Pod的规格,此部分定义Pod中每一个容器的属性,期中name和image是必需的;
  9. volumes指定了应用使用的存储卷,其中containers下定义容器挂载的卷;

主流币对比分析

发表于 2018-04-08 | 分类于 区块链 | | 阅读次数:

主流币对比分析

1、BTC(比特币)

比特币(Bitcoin,简称BTC)是目前使用最为广泛的一种数字货币,它诞生于2009年1月3日,是一种点对点(P2P)传输的数字加密货币。

1
2
3
4
5
6
7
8
9
10
11
最大量:21000000BTC
市值:1800亿(美金)
共识机制:POW
发行时间:2008-11-1
核心算法:SHA-256
研发者:Satoshi Nakamoto

区块奖励:当前12.5BTC/区块(每产出21万个区块/约每四年减半一次,最近一次减半时间:2016年7月9日)
区块时间:约600秒/块

标签:基础链、货币

白皮书:https://bitcoin.org/bitcoin.pdf
官方网站:https://bitcoin.org/zh_CN/
比特币常见问题:https://bitcoin.org/zh_CN/faq
区块查询:https://blockchain.info/
比特币论坛:https://bitcointalk.org/
市值查询网站:https://coinmarketcap.com/

2、ETH(以太币)

以太坊是开源平台数字货币和区块链平台,它为开发者提供在区块链上搭建和发布应用的平台。

1
2
3
4
5
6
7
8
9
10
11
12
最大量:9631.15万
市值:850亿
共识机制:POW
发行时间:2014-07-24
核心算法:Ethash
研发者:Vitalik Buterin

区块奖励:5
区块时间:约15-17秒/块
主要特色:含数字货币和智能合约等特色功能

标签:基础链

白皮书:https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-White-Paper
官方网站:https://www.ethereum.org/
区块查询:https://etherscan.io/

3、XRP(瑞波币)

瑞波币(Ripple/XRP)提供一个无阻碍的利用区块链技术的全球支付网络,是世界上第一个开放的支付网络。

1
2
3
4
5
6
7
8
9
10
11
最大量:10000000万
市值:380亿
发行时间:2014-07-24
核心算法:OpenCoin原创算法
研发者:Ripple Labs

区块时间:秒到
主要特色:Google旗下投资,去中心化交易功能已经实现,实际应用前景好
注:瑞波币(XRP)是中心化的造币和分配方式

标签:结算

项目官网:https://ripple.com/
区块链浏览器:https://xrpcharts.ripple.com/#/graph/

4、BCH(比特币现金)

BCH是根据Bitcoin ABC方案产生的区块链资产。Bitcoin ABC方案为保持协议稳定简单,去除了Segwit功能,支持将区块大小提升至8M,是链上扩容的技术路线。(比特币硬分叉产生的币)

1
2
3
4
5
6
7
8
9
最大量:21000000BCH
市值:220亿
共识机制:POW
发行时间:2017-08-01
核心算法:SHA-256

主要特色:区块大小最高支持8MB;EDA难度调整机制

标签:货币、分叉币

官方网站:https://www.bitcoincash.org/
区块查询:http://blockdozer.com/insight/

5、LTC(莱特币)

莱特币被称为是“数字白银”。莱特币在技术上和比特币具有相同的实现原理。它是第一个基于Scrypt算法的网络数字货币,与比特币相比,莱特币拥有更快的交易确认时间,更高的网络交易容量和效率。

1
2
3
4
5
6
7
8
9
10
11
12
最大量:8400万
市值:120亿
共识机制:POW
发行时间:2011-11-09
核心算法:Scrypt
研发者:Charlie Lee

区块奖励:最初50LTC,当前25LTC
区块时间:150秒/块
主要特色:发行量大:发行量是比特币的4倍;交易快速:确认时间仅2.5分钟;隔离验证激活

标签:货币

官方网站:https://litecoin.org/
区块查询:http://explorer.litecoin.net/

6、ADA(Cardano)

Cardano是一个完全开源的区块链平台。Cardano是世界上第一个由研究为主导,并严格采用科学方法(数学)来证明严谨,安全性的区块链。Cardano的目标不是构建一个类似于以太坊,智能合约的协议,Cardano的目标是构建一个分层次的区块链生态系统。

1
2
3
4
5
6
7
8
9
最大量:45亿
市值:90亿
发行时间:2017-10-02
研发者:Charles Hoskinson 和 Jeremy Wood

区块奖励:3.5分钟
区块时间:每个区块产生2000个艾达币(逐渐减半)

标签:基础链

白皮书:https://www.cardanohub.org/zh/academic-papers-3/
官网:https://www.cardanohub.org/

7、NEO

利用区块链技术和数字身份进行资产数字化,利用智能合约对数字资产进行自动化管理,实现“智能经济”的一种分布式网络。

1
2
3
4
5
6
7
8
9
10
11
最大量:1亿
市值:80亿
ICO时间:2015-10(0.28元)
共识算法:dBFT
核心算法:Lattice
研发者:Charles Hoskinson 和 Jeremy Wood

代币产生:ICO发售
代币功能:NEO 管理代币的持有人是 NEO 网络的所有者和管理者,通过在 NEO 网络上构造投票交易来实现管理权,通过获得 NEO 管理代币所对应的 GAS 燃料代币来实现 NEO 网络的使用权。

标签:基础链

白皮书:http://docs.neo.org/zh-cn/
官网:https://neo.org
区块查询:https://neotracker.io/

8、XLM(恒星币)

用于搭建一个数字货币与法定货币之间传输的去中心化网关。基于Ripple代码修改创建的恒星支付网络中的基础数字货币。

1
2
3
4
5
6
7
8
最大量:1000亿
市值:65亿
共识算法:SCP
研发者:Jed Mccaleb

特点:恒星协议的独特性是一个实现了增发的系统。每年增加1%的STR,并每周分发。网络中的账户可以通过在帐号设置(AccountSet)事务中设置“增发对象”来为另外一个地址“投票”。[9] 每个账户的投票权重基于其持有的STR数量。每个周末,增发的STR会发给前50个帐号。

标签:结算

官网:https://www.stellar.org/cn/?noredirect=zh

9、*EOS

EOS (Enterprise Operation System)是由 Block.one公司主导开发的一种全新的基于区块链智能合约平台,旨在为高性能分布式应用提供底层区块链平台服务。EOS 项目的目标是实现一个类似操作系统的支撑分布式应用程序的区块链架构。该架构可以提供账户,身份认证,数据库,异步通信以及可在数以万计的 CPU/GPU群集上进行程序调度和并行运算。EOS最终可以支持每秒执行数百万个交易,同时普通用户执行智能合约无需支付使用费用。

1
2
3
4
5
6
7
8
9
最大量:10亿
市值:50亿
发行时间:2017-6-26

代币:不需要挖矿

特点:EOS代币目前是EOS区块链基础设施发布的基于以太坊的代币,主要有三大应用场景:带宽和日志存储(硬盘),计算和计算储备(CPU),状态存储(RAM)。EOS主网上线后会将ERC20代币EOS转换为其主链上的代币。

标签:基础链

白皮书
https://github.com/EOSIO/Documentation/blob/master/zh-CN/TechnicalWhitePaper.md
官网
https://eos.io/
区块查询
https://etherscan.io/token/EOS

10、DASH(达世币)

一种开源的点对点(P2P)加密货币,能够提供即时交易、匿名交易和替代货币功能。

1
2
3
4
5
6
7
8
9
10
11
12
最大量:2100万
市值:48.5亿
共识机制:POW
核心算法:X11
发行时间:2014-01-18
研发者:Evan Duffield

区块奖励:3.6个达世币(矿工获得45%的回报,主节点收到45%,剩余的10%则分配给去中心化的达世币预算系统)
区块时间:150秒/块
主要特色:匿名性高、即时发送、自管理系统。

标签:匿名币

白皮书
https://dashpay.atlassian.net/wiki/spaces/DOC/pages/5472261/Whitepaper
官网
https://www.dash.org
区块查询
https://chainz.cryptoid.info/dash

11、IOT

IOTA是物联网面临的基础设施挑战的解决方案,是一个去中心化物联网加密货币平台。

1
2
3
4
5
6
7
8
9
10
11
12
最大量:27.79亿
市值:47亿
发行时间:2015-1-25
研发者:Serguei Popov

代币:不需要挖矿

代币:所有IOTA都是在初始块创建的,总数不变,也不用开采,IOTA是非通货膨胀的。
因为没有矿工挖矿,IOTA把所有的代币通过认购进行分发。
特点:基于新型的分布式账本——Tangle,能够克服现有区块链设计中的低效性,具有零传输费用、无限扩展、数据安全等新特性。

标签:物联网

官网
https://iota.org

12、XMR(门罗币)

门罗币提出了一种不依赖于中心节点的加密混合方案。门罗币的关键技术有两个,一个叫做隐蔽地址(stealth address),另一个叫做环签名(ring signature)。

1
2
3
4
5
6
7
8
9
10
11
12
最大量:1844万
市值:44亿
核心算法:CryptoNote
发行时间:2014-4-18
研发者:门罗币团队

区块时间:60秒
区块奖励:不定

特点:门罗币是目前唯一能隐藏交易发起者,接收者,交易金额,和交易IP的加密货币。在国外geek/黑客/暗网中声誉非常高。基于新数字环签名的一种数字货币

标签:匿名币

官网:https://getmonero.org/

13、XEM(新经币)

NEM的创立目标是创建一套全新的数字货币及其生态系统。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
最大量:90亿
市值:36亿
英文名称:New Economy Model,缩写NEM
代币名称:XEM
共识算法:POI(重要性证明)
挖矿方式:Harvest
发行时间:2015-4-1
代码基础:主链从零编写(Java)
研发团队:以美洲虎Jaguar为首的一群经验丰富的技术极客

区块时间:60秒

特点:NEM具有独创的命名空间/智能资产系统,类似于互联网时代的域名/页面的结构,每个用户都可以便捷的申请属于自己的命名空间,并在公有链上发布链上资产。

标签:货币

官网:https://nem.io/ 及 http://www.nemchina.com/
白皮书:https://nem.io/wp-content/themes/nem/files/NEM_techRef.pdf
区块链浏览器:http://chain.nem.ninja/

14、ETC(以太经典)

以太坊开发团队通过修改以太坊软件的代码,“夺回”黑客所控制的DAO合约的币。从而形成两条链,一条为原链(ETC),一条为新的分叉链(ETH)。一群坚持区块链核心价值的开发者组成Ethereum Classic,发行独立的加密货币ETC。

1
2
3
4
5
6
7
8
9
10
最大量:2.3亿
市值:35亿
共识算法:POW
核心算法:Ethash
发行时间:2016-7-20
研发团队:以太经典团队

区块时间:约15-17秒/块

标签:基础链

官方网站:https://ethereumclassic.github.io/
区块查询:https://gastracker.io/

15、*TRX(波场)

波场TRON是基于区块链的开源去中心化内容娱乐协议。它致力于利用区块链与分布式存储技术,构建一个全球范围内的自由内容娱乐体系,这个协议可以让每个用户自由发布,存储,拥有数据,并通过去中心化的自治形式,以数字资产发行,流通。交易方式决定内容的分发、订阅、推送,赋能内容创造者,形成去中心化的内容娱乐生态。

1
2
3
4
5
6
7
8
最大量:1000亿
市值:26亿
发行时间:2017-9-14
研发团队:波场团队

代币:不需要挖矿

标签:娱乐

白皮书:https://dn-peiwo-web.qbox.me/Tron-Whitepaper-1008-V19-5.pdf
官网:https://tron.network
区块查询:https://etherscan.io/address/0xf230b790e0539

16、VEN(唯链)

全球领先的区块链商品和信息平台。项目旨在解决商业社会中产品的信息和信任问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
最大量:10亿
市值:25亿
发行时间:2017-8-23
研发团队:唯链团队

代币:不需要挖矿
项目代币:10亿(ICO有退币,并销毁)
ICO比例:41%
私募投资人:9%
企业投资人:23%
创始团队+开发团队:5%
持续经营及技术发展:12%
商业落地推广:10%
代币定价:0.5CNY/枚

标签:真实性验证、防伪溯源

官网:https://www.vechain.com/
白皮书:https://cdn.vechain.com/vechain_ico_ideas_of_development_cn.pdf

17、LSK(应用链)

Lisk基于自己的区块链网络和代币LSK,使开发人员能够构建应用程序,并部署自己的侧链链接到Lisk网络。由于侧链的可扩展性和灵活性,开发人员可以完全实现和定制他们的区块链应用程序。

1
2
3
4
5
6
7
8
9
10
最大量:1.17亿
市值:23亿
发行时间:2016-2-22
共识算法:DPoS

代币总量:初始100,000,000,随区块产生不断增加

特点:第一个完全写在JS里的去中心化应用解决方案。

标签:基础链

项目网站:https://lisk.io
白皮书:https://docs.lisk.io/docs/the-lisk-protocol

18、BTG(比特币黄金)

比特币黄金是在2017年10月25日左右的又一次比特币硬分叉产物。

1
2
3
4
市值:19亿
特点:比特币黄金是对大矿工们集中算力的一种对抗。比特币黄金将使用一种新算法来避免情况恶化,这种算法对ASIC非常不友好,这将导致矿工们转而使用GPU,而GPU价格便宜得多。

标签:分叉币

官方网站: https://bitcoingold.org/#features

19、*QTUM(量子链)

Qtum Blockchain(简称“量子链”或“Qtum”)致力于开发比特币和以太坊之外的第三种区块链生态系统,通过价值传输协议(“Value Transfer Protocol”)来实现点对点的价值转移,并根据此协议,构建一个支持多个行业(包括金融、物联网、供应链、社交、游戏等)的去中心化的应用开发平台(“DApp Platform”)。

1
2
3
4
5
市值:19亿
发行时间:2017-3
特点:Dapp使用权/代币投票/社区自治/使用应用功能消耗/支付。

标签:面向移动端的基础链

官网:https://www.qtum.org/zh/
白皮书:https://www.qtum.org/zh/white-papers

20、*OMG(OmiseGO)

OmiseGO是一个去中心化交易和支付平台。

1
2
3
4
5
6
总量:14024.54万
市值:17亿
发行时间:2017-6-27
特点:基于以太坊实现实时的点对点价值交换和支付服务。

标签:金融服务、支付

白皮书:https://cdn.omise.co/omg/whitepaper.pdf
官网:https://omg.omise.co
区块查询:https://etherscan.io/token/OmiseGo

附:共识机制

  • 工作量证明算法(PoW):
    依赖机器进行数学运算来获取记账权,资源消耗相比其他共识机制高、可监管性弱,同时每次达成共识需要全网共同参与运算,性能效率比较低,容错性方面允许全网50%节点出错。
1
2
3
4
5
6
7
8
9
10
优点:
1)算法简单,容易实现;
2)节点间无需交换额外的信息即可达成共识;
3)破坏系统需要投入极大的成本;
缺点:
1)浪费能源;
2)区块的确认时间难以缩短;
3)新的区块链必须找到一种不同的散列算法,否则就会面临比特币的算力攻击;
4)容易产生分叉,需要等待多个确认;
5)永远没有最终性,需要检查点机制来弥补最终性;
  • 权益证明算法(PoS):类似股权凭证和投票系统,因此也叫“股权证明算法”。PoS首先选出“记账人”,由它负责创建区块,持有最多(coin)的就拥有最大的特权,也要负担更大的责任来创建区块,同时获得更多的收益。PoS希望能尽可能的减少运算资源,达成共识。
1
2
3
4
5
6
优点:
1)节省计算资源
缺点:
1)没有专业化,拥有权益的参与者未必希望参与记账;
2)容易产生分叉,需要等待多个确认;
3)永远没有最终性,需要检查点机制来弥补最终性;
  • 股份授权证明机制(DPoS):与PoS共识算法相似,区别是DPoS采取了间接民主代议制。它试图解决PoW和PoS遗留下的问题,通过引入间接民主代议制抵消集中化引起的负面影响

  • dBFT:是由权益来选出记账人,然后记账人之间通过拜占庭容错算法来达成共识。dBFT机制最核心的一点,就是最大限度地确保系统的最终性

1
2
3
4
5
6
7
8
9
优点:
1)专业化的记账人;
2)可以容忍任何类型的错误;
3)记账由多人协同完成,每一个区块都有最终性,不会分叉;
4)算法的可靠性有严格的数学证明;

缺点:
1)当有1/3或以上记账人停止工作后,系统将无法提供服务;
2)当有1/3或以上记账人联合作恶,且其它所有的记账人被恰好分割为两个网络孤岛时,恶意记账人可以使系统出现分叉,但是会留下密码学证据;

virtualenv与pipenv简介

发表于 2018-04-08 | 分类于 python | | 阅读次数:

virtualenv

virtualenv用来为一个应用创建一套“独立”的Python运行环境。

安装virtualenv

1
pip install virtualenv

如果现新项目需要使用独立的python运行环境,具体步骤如下:
一、创建工程目录

1
2
mkdir myproject
cd myproject

二、使用virtualenv创建独立的Python运行环境(此处命名为pyenv)
“-p”指定使用的python版本环境

1
virtualenv -p python2/python3 pyenv

virtualenv已经成功创建了一个独立的Python运行环境,如果附上参数–no-site-packages,那么已经安装到系统Python环境中的所有第三方包都不会复制过来,这样我们可以得到了一个不带任何第三方包的“干净”的Python运行环境。

三、进入新环境同时安装依赖

1
2
source pyenv/bin/activate
pip/pip3 install package

在pyenv环境下,用pip安装的包都被安装到pyenv这个环境下,系统Python环境不受任何影响。pyenv环境是专门针对myproject这个应用创建的。

四、使用deactivate退出当前pyenv环境

1
deactivate

工作原理:

virtualenv把系统Python复制一份到virtualenv的环境,用命令source pyenv/bin/activate进入一个virtualenv环境时,virtualenv会修改相关环境变量,让命令python和pip均指向当前的virtualenv环境。

pipenv

pipenv整合了virtualenv, pip, Pipfile,用于更方便地为项目建立虚拟环境并管理虚拟环境中的第三方模块。Pipfile是社区拟定的依赖管理文件,用于替代过于简陋的requirements.txt文件。

Pipfile文件是TOML格式而不是requirements.txt这样的纯文本。一个项目对应一个Pipfile,支持开发环境与正式环境区分。默认提供default和development区分。同时提供版本锁支持,存为Pipfile.lock。

安装pipenv

1
pip install pipenv

常用指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
pipenv --two/--three //指定python2/python3运行版本

pipenv -p /usr/bin/python2.7 //指定python版本

pipenv shell //激活虚拟环境

pipenv --venv //显示虚拟环境信息
/Users/fengzefeng/.local/share/virtualenvs/blockchain-hW9mDy3h

pipenv --py //显示Python解释器信息
/Users/fengzefeng/.local/share/virtualenvs/blockchain-hW9mDy3h/bin/python

pipenv install requests 安装相关插件并加入到Pipfile

pipenv install django==1.11 指定插件版本并加入到Pipfile

pipenv graph //查看目前安装的插件及其依赖

pipenv check //检查安全漏洞

pipenv uninstall --all //卸载全部包并从Pipfile中移除

pipenv lock 将安装插件更新到Pipfile.lock中

pipenv clean 删除所有未在Pipfile.lock中指定的模块

pipenv install安装列表是通过读取pipfile, pipfile.lock文件实现的,如果没有这两个文件就根据requirements.txt生成pipfile和pipfile.lock并读取。单独安装模块后会自动将新模块信息添加到pipfile中, 要同时更新pipfile.lock需要运行:pipenv lock。

pipenv新建的虚拟环境放在统一的目录下, 在某个目录下运行pipenv shell时pipenv会自动在虚拟环境目录下搜索以当前目录名称开头的虚拟环境目录, 如果没找到则判断为无虚拟环境.

Solidity语法简介

发表于 2018-04-04 | 分类于 区块链 | | 阅读次数:

版本指令

所有的Solidity源码都必须冠以version pragma标明Solidity编译器的版本.以避免将来新的编译器可能破坏你的代码。

1
pragma solidity ^0.4.19;


Contract

Solidity 的代码都包裹在合约里面。一份合约就是以太应币应用的基本模块,所有的变量和函数都属于一份合约, 它是你所有应用的起点。

1
2
3
contract HelloWorld {
...
}


状态变量和整数

状态变量是被永久地保存在合约中。也就是说它们被写入以太币区块链中. 想象成写入一个数据库。

无符号整数: uint

uint无符号数据类型,指其值不能是负数,对于有符号的整数存在名为int的数据类型。Solidity中,uint实际上是 uint256代名词,一个256位的无符号整数。

1
2
3
4
contract Test {
// 这个无符号整数将会永久的被保存在区块链中
uint myUnsignedInteger = 100;
}

类型转换

1
2
3
4
5
6
uint8 a = 5;
uint b = 6;
// 将会抛出错误,因为 a * b 返回 uint, 而不是 uint8:
uint8 c = a * b;
// 我们需要将 b 转换为 uint8:
uint8 c = a * uint8(b);

上面, a * b返回类型是uint, 但是当我们尝试用uint8类型接收时, 就会造成潜在的错误。如果把它的数据类型转换为 uint8就可以了,编译器也不会出错。


映射(Mapping)和地址(Address)

Addresses (地址)

以太坊区块链由 account (账户)组成,你可以把它想象成银行账户。一个帐户的余额是以太(在以太坊区块链上使用的币种),你可以和其他帐户之间支付和接受以太币,就像你的银行帐户可以电汇资金到其他银行帐户一样。每个帐户都有一个唯一“地址”。

Mapping(映射)

映射是另一种在Solidity中存储有组织数据的方法。映射是这样定义的:

1
2
3
4
//对于金融应用程序,将用户的余额保存在一个uint类型的变量中:
mapping (address => uint) public accountBalance;
//或者可以用来通过userId 存储/查找的用户名
mapping (uint => string) userIdToName;

映射本质上是存储和查找数据所用的键-值对。在第一个例子中,键是一个address,值是一个 uint,在第二个例子中,键是一个uint,值是一个string。


结构体

有时你需要更复杂的数据类型,Solidity提供了结构体:

1
2
3
4
5
struct Person {
uint age;
string name;
}
Person p = Person(12, "peter");

结构体允许你生成一个更复杂的数据类型,它有多个属性。

您可以用p.age或p.name访问p的属性。如果一个struct中有多个uint,则尽可能使用较小的uint,Solidity会将这些uint打包在一起,从而占用较少的存储空间(一般情况下,无论如何定义uint的大小,Solidity为它保留256位的存储空间)。


数组

如果你想建立一个集合,可以用数组这样的数据类型. Solidity支持两种数组: 静态数组和动态数组:

1
2
3
4
5
6
// 固定长度为2的静态数组:
uint[2] fixedArray;
// 固定长度为5的string类型的静态数组:
string[5] stringArray;
// 动态数组,长度不固定,可以动态添加元素:
uint[] dynamicArray;

公共数组

你可以定义public数组, Solidity会自动创建getter方法. 语法如下:

1
Person[] public people;

其它的合约可以从这个数组读取数据(但不能写入数据),所以这在合约中是一个有用的保存公共数据的模式。

array.push() 在数组的尾部加入新元素,所以元素在数组中的顺序就是我们添加的顺序.

1
2
3
4
uint[] numbers;
numbers.push(5);
numbers.push(10);
// numbers is now equal to [5, 15]


函数

在 Solidity 中函数定义的句法如下:

function echoStudent(string _name, uint amount) returns(bool isReady, uint genes){
…
}
这是一个名为echoStudent的函数,它接受两个参数:一个string类型的和一个uint类型的。(习惯上函数里的变量都是以
开头以区别全局变量)。在Solidity中,您可以让一个函数返回多个值。

函数可见性

Solidity定义的函数的属性默认为公共。显然,不是什么时候都需要这样,而且这样的合约易于受到攻击。 所以将自己的函数定义为私有是一个好的编程习惯,只有当你需要外部世界调用它时才将它设置为公共。

  • public
    任何一方 (或其它合约)都可以调用你合约里的函数;
  • private
    这意味着即使是继承自合约的子合约都不能访问它。
  • internal
    internal和private 类似,不过,如果某个合约继承自其父合约,这个合约即可以访问父合约中定义的“内部”函数。
  • external
    external与public类似,只不过这些函数只能在合约之外调用。它们不能被合约内的其他函数调用。
1
2
3
4
5
uint[] numbers;

function _addToArray(uint _number) private {
numbers.push(_number);
}

这意味着只有我们合约中的其它函数才能够调用这个函数,给numbers数组添加新成员。
可以看到,在函数名字后面使用关键字private即可。和函数的参数类似,私有函数的名字用 _ 起始。

函数返回值

要想函数返回一个数值,按如下定义:

1
2
3
4
string greeting = "What's up dog";
function sayHello() public returns (string) {
return greeting;
}

Solidity里,函数的定义里可包含返回值的数据类型。当函数有多个返回值时,可以这么使用(,,c)=func(“”),可以对指定字段留空。

函数的修饰符

上面的函数实际上没有改变 Solidity 里的状态,即,它没有改变任何值或者写任何东西。
这种情况下我们可以把函数定义为view, 意味着它只能读取数据不能更改数据:

1
function sayHello() public view returns (string) {...}

Solidity 还支持pure函数, 表明这个函数甚至都不访问应用里的数据,例如:

1
2
3
function _multiply(uint a, uint b) private pure returns (uint) {
return a * b;
}

这个函数甚至都不读取应用里的状态,它的返回值完全取决于它的输入参数,在这种情况下我们把函数定义为pure.


事件

事件是合约和区块链通讯的一种机制。你的前端应用“监听”某些事件,并做出反应。

1
2
3
4
5
6
7
8
9
// 这里建立事件
event IntegersAdded(uint x, uint y, uint result);

function add(uint _x, uint _y) public {
uint result = _x + _y;
//触发事件,通知app
IntegersAdded(_x, _y, result);
return result;
}

你的 app 前端可以监听这个事件。JavaScript 实现如下:

1
2
3
YourContract.IntegersAdded(function(error, result) { 
// 干些事
}


继承

有个让Solidity的代码易于管理的功能,就是合约inheritance(继承):

1
2
3
4
5
6
7
8
9
10
11
contract Doge {
function catchphrase() public returns (string) {
return "So Wow CryptoDoge";
}
}

contract BabyDoge is Doge {
function anotherCatchphrase() public returns (string) {
return "Such Moon BabyDoge";
}
}

由于BabyDoge是从Doge那里继承过来的。这意味着当你编译和部署了BabyDoge,它将可以访问catchphrase()和 anotherCatchphrase()和其他我们在Doge中定义的其他公共函数。
这可以用于逻辑继承(比如表达子类的时候,Cat是一种Animal)。 但也可以简单地将类似的逻辑组合到不同的合约中以组织代码。


Storage与Memory

在Solidity中,有两个地方可以存储变量——storage或memory。

Storage变量是指永久存储在区块链中的变量。Memory变量则是临时的,当外部函数对某合约调用完成时,内存型变量即被移除。你可以把它想象成存储在你电脑的硬盘或是RAM中数据的关系。

大多数时候你都用不到这些关键字,默认情况下Solidity会自动处理它们。状态变量(在函数之外声明的变量)默认为“存储”形式,并永久写入区块链;而在函数内部声明的变量是“内存”型的,它们函数调用结束后消失。

然而也有一些情况下,你需要手动声明存储类型,主要用于处理函数内的结构体和数组时:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
contract SandwichFactory {
struct Sandwich {
string name;
string status;
}

Sandwich[] sandwiches;

function eatSandwich(uint _index) public {
// Sandwich mySandwich = sandwiches[_index];

// ^ 看上去很直接,不过 Solidity 将会给出警告
// 告诉你应该明确在这里定义 `storage` 或者 `memory`。

// 所以你应该明确定义 `storage`:
Sandwich storage mySandwich = sandwiches[_index];
// ...这样 `mySandwich` 是指向 `sandwiches[_index]`的指针
// 在存储里,另外...
mySandwich.status = "Eaten!";
// ...这将永久把 `sandwiches[_index]` 变为区块链上的存储

// 如果你只想要一个副本,可以使用`memory`:
Sandwich memory anotherSandwich = sandwiches[_index + 1];
// ...这样 `anotherSandwich` 就仅仅是一个内存里的副本了
// 另外
anotherSandwich.status = "Eaten!";
// ...将仅仅修改临时变量,对 `sandwiches[_index + 1]` 没有任何影响
// 不过你可以这样做:
sandwiches[_index + 1] = anotherSandwich;
// ...如果你想把副本的改动保存回区块链存储
}
}


其它

Keccak256

Ethereum内部有一个散列函数keccak256,它用了SHA3版本。一个散列函数基本上就是把一个字符串转换为一个256位的16进制数字。字符串的一个微小变化会引起散列数据极大变化。

1
2
3
4
//6e91ec6b618bb462a4a6ee5aa2cb0e9cf30f7a052bb467b0ba58b8748c00d2e5
keccak256("aaaab");
//b1f078126895a1424524de5321b339ab00408010b7cf0e6ed451514981e58aa9
keccak256("aaaac");

msg.sender

在Solidity中,有一些全局变量可以被所有函数调用。其中一个就是msg.sender,它指的是当前调用者(或智能合约)的address。在Solidity中,功能执行始终需要从外部调用者开始。 一个合约只会在区块链上什么也不做,除非有人调用其中的函数。所以msg.sender总是存在的。
使用 msg.sender很安全,因为它具有以太坊区块链的安全保障。除非窃取与以太坊地址相关联的私钥,否则是没有办法修改其他人的数据的。

1
2
3
4
5
6
7
8
9
10
11
12
13
mapping (address => uint) favoriteNumber;

function setMyNumber(uint _myNumber) public {
// 更新我们的 `favoriteNumber` 映射来将 `_myNumber`存储在 `msg.sender`名下
favoriteNumber[msg.sender] = _myNumber;
// 存储数据至映射的方法和将数据存储在数组相似
}

function whatIsMyNumber() public view returns (uint) {
// 拿到存储在调用者地址名下的值
// 若调用者还没调用 setMyNumber, 则值为 `0`
return favoriteNumber[msg.sender];
}

Require

require使得函数在执行过程中,当不满足某些条件时抛出错误,并停止执行:

1
2
3
4
5
6
7
8
function sayHiToVitalik(string _name) public returns (string) {
// 比较 _name 是否等于 "Vitalik". 如果不成立,抛出异常并终止程序
// (敲黑板: Solidity 并不支持原生的字符串比较, 我们只能通过比较
// 两字符串的 keccak256 哈希值来进行判断)
require(keccak256(_name) == keccak256("Vitalik"));
// 如果返回 true, 运行如下语句
return "Hi!";
}

import

在Solidity 中,当你有多个文件并且想把一个文件导入另一个文件时,可以使用import语句:

1
2
3
4
import "./someothercontract.sol";
contract newContract is SomeOtherContract {

}

这样当我们在合约(contract)目录下有一个名为someothercontract.sol的文件(./就是同一目录的意思),它就会被编译器导入。

与其他合约的交互

如果我们的合约需要和区块链上的其他的合约会话,则需先定义一个 interface (接口)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 区块链上有这么一个合约
contract LuckyNumber {
mapping(address => uint) numbers;

function setNum(uint _num) public {
numbers[msg.sender] = _num;
}

function getNum(address _myAddress) public view returns (uint) {
return numbers[_myAddress];
}
}
...

# interface
contract NumberInterface {
function getNum(address _myAddress) public view returns (uint);
}
...

# interface调用
contract MyContract {
address NumberInterfaceAddress = 0xab38...;
// ^ 这是FavoriteNumber合约在以太坊上的地址
NumberInterface numberContract = NumberInterface(NumberInterfaceAddress);
// 现在变量 `numberContract` 指向另一个合约对象

function someFunction() public {
// 现在我们可以调用在那个合约中声明的 `getNum`函数:
uint num = numberContract.getNum(msg.sender);
// ...在这儿使用 `num`变量做些什么
}
}

getNum没有使用到任何其他的函数或状态变量。没有使用大括号({ 和 })定义函数体,单用分号(;)结束了函数声明。这使它看起来像一个合约框架。编译器就是靠这些特征认出它是一个接口的。
通过这种方式,只要将您合约的可见性设置为public(公共)或external(外部),它们就可以与以太坊区块链上的任何其他合约进行交互。

智能协议的永固性

在你把智能协议传上以太坊之后,它就变得不可更改, 这种永固性意味着你的代码永远不能被调整或更新。你编译的程序会一直,永久的,不可更改的,存在以太网上。这就是Solidity代码的安全性如此重要的一个原因。如果你的智能协议有任何漏洞,即使你发现了也无法补救。你只能让你的用户们放弃这个智能协议,然后转移到一个新的修复后的合约上。

但这恰好也是智能合约的一大优势。 代码说明一切。 如果你去读智能合约的代码,并验证它,你会发现, 一旦函数被定义下来,每一次的运行,程序都会严格遵照函数中原有的代码逻辑一丝不苟地执行,完全不用担心函数被人篡改而得到意外的结果。因此我们不能硬编码,而要采用“函数”,以便于DApp的关键部分可以以参数形式修改。

Ownable合约

Ownable特性:
1、合约创建时,在构造函数将owner设置为msg.sender(其部署者);
2、为它加上一个修饰符onlyOwner,它会限制陌生人的访问,将访问某些函数的权限锁定在owner上。
3、允许将合约所有权转让给他人。

函数修饰符:modifier onlyOwner()。修饰符跟函数很类似,不过是用来修饰其他已有函数用的,在其他语句执行前,为它检查下先验条件。在这个例子中,我们就可以写个修饰符onlyOwner检查下调用者,确保只有合约的主人才能运行本函数。

1
2
3
4
5
6
7
/**
* @dev 调用者不是‘主人’,就会抛出异常
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}

尽管函数修饰符也可以应用到各种场合,但最常见的还是放在函数执行之前添加快速的 require检查。因为给函数添加了修饰符onlyOwner,使得唯有合约的主人(也就是部署者)才能调用它。

Solidity时间

1
2
3
4
5
6
年 years
周 weeks
天 days
小时 hours
分钟 minutes
秒 seconds

节省Gas的方法:

1、使用struct将uint打包一起;
2、利用View函数节省Gas。

payable修饰符

payable方法是让Solidity和以太坊变得如此酷的一部分,它们是一种可以接收以太的特殊函数。但是在以太坊中,因为钱(以太), 数据(事务负载),以及合约代码本身都存在于以太坊。你可以在同时调用函数 并付钱给另外一个合约。
你可以通过transfer函数向一个地址发送以太,然后this.balance将返回当前合约存储了多少以太。


12

Lory Feng

fight!

15 日志
9 分类
28 标签
GitHub E-Mail
© 2021 Lory Feng
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4
粤ICP备18017208号