• 粉丝日志首页

用R语言实现数据离散化

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹(Conan), 程序员/Quant: Java,R,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-discretization

前言

在做数据挖掘模型的时候,我们有时会需要把连续型变量转型离散变量,这种转换的过程就是数据离散化,分箱就是离散化常用的一种方法。

数据离散化处理属于数据预处理的一个过程,R语言在数据处理上有天然的优势,也有直接用于离散化计算的包,无监督的离散化可以用infotheo包,有监督的离散化可以用discretization包来处理复杂的离散化操作。

目录

  1. 数据离散化的需求
  2. 无监督的数据离散化
  3. 有监督的数据离散化

1. 数据离散化的需求

数据离散化,教课书上面的定义是,把无限空间中有限的个体映射到有限的空间中。数据离散化操作,大多是针对连续型变量进行的,处理之后数据从连续型变量转变为离散型变量。

离散化处理的特点:

  • 快速迭代,离散化的过程,离散特征增加和减少都很容易,易于扩展。
  • 高效计算,稀疏向量内积乘法运算速度快,计算结果方便存储。
  • 适应性,有些分类模型适合用离散化数据做为数据指标,比如决策树虽然支持输入连续型变量,但决策树模型本身会先将连续型变量转化为离散型变量,做逻辑回归时,也通常会先把连续型特征变量离散化,变成0或1。
  • 鲁棒性,数据离散化会让特征变化不是特别明显,特别是对于降低异常数据干扰。
  • 稳定性,牺牲了数据的微小变化,但保证了模型的稳定性。
  • 过拟合,减少的数据信息,降低了过拟合的风险。
  • 业务性,业务上已经定义出了离散值的含义,需要做离散化处理。

离散化处理通常对连续型变量进行处理,但同时也可以对离散型变量再进行离散化,适用于数据聚合或重新分组。

2. 无监督的数据离散化

我们可以无监督的数据离散化方法,进行数据的分箱操作,包括等宽分箱法、等频分箱法、通过kmeans分箱法等。

  • 等宽分箱法,将观察点均匀划分成n等份,每份的间距相等。
  • 等频分箱法,将观察点均匀分成n等份,每份的观察点数相同。
  • kmeans分箱法,先给定中心数,将观察点利用欧式距离计算与中心点的距离进行归类,再重新计算中心点,直到中心点不再发生变化,以归类的结果做为分箱的结果。

接下来,我们用R语言来实现上面提到的几种分箱的操作。

2.1 准备数据

本文所使用的系统环境

  • Win10 64bit
  • R: 3.2.3 x86_64-w64-mingw32/x64 b4bit

首先,生成一组数据,这组织通过3个正态分布的随机数进行叠加,主要用于体现分箱的不同特征。


# 设置随机数种子,生成符合正态分布N(0,1)的数据1000个点
> set.seed(0)
> a1<-rnorm(1000)

> set.seed(1)
> a2<-rnorm(300,0,0.2)

> set.seed(2)
> a3<-rnorm(300,3,0.5)

# 按顺序,合并3种数据
> aa<-c(a1,a2,a3)

# 查看数据
> head(aa,30)
 [1]  1.26295 -0.32623  1.32980  1.27243  0.41464 -1.53995 -0.92857 -0.29472 -0.00577  2.40465  0.76359
[12] -0.79901 -1.14766 -0.28946 -0.29922 -0.41151  0.25222 -0.89192  0.43568 -1.23754 -0.22427  0.37740
[23]  0.13334  0.80419 -0.05711  0.50361  1.08577 -0.69095 -1.28460  0.04673

画出数据的散点图,x轴为索引序号,y轴为值。


> plot(aa)

查看数据的分布形状,x轴为值,y轴为这个值出现的次数。


# 画出数据的直方图
> hist(aa,200)

通过散点图和直方图,就可以很明显的看到数据的特征,数据有倾斜的,值在0和3附近是比较多的。

2.2 infotheo包使用

在R语言中,我们可以使用infotheo包,来做等宽分箱和等频分箱。

项目主页:https://cran.r-project.org/web/packages/infotheo/

安装infotheo包,是非常简单的,只需要一条命令。


~ R
> install.packages("infotheo")
> library(infotheo)

进行等宽分箱,将观察点均匀划分成n等份,每份的间距相等。


> d1<-discretize(aa,"equalwidth",5)
> table(d1)
d1
  1   2   3   4   5 
 40 467 703 217 173 

# 可视化分箱
> plot(aa,col=d1$X)

分为5组,第一组最少,第三组最多,每组值的区间是一样的。

进行等频率分箱,将观察点均匀分成n等份,每份的观察点数相同。


> d2<-discretize(aa,"equalfreq",5)
> table(d2)
d2
  1   2   3   4   5 
320 320 320 320 320 

# 可视化分箱
> plot(aa,col=d2$X)

分为5组,每组的数量都相同。

kmeans分箱法,先给定中心数为5。


> d3<-kmeans(aa,5)
> table(d3$cluster)
  1   2   3   4   5 
121 258 303 267 651 

# 5个中心
> d3$centers
     [,1]
1 -1.6196
2  1.2096
3  3.0436
4 -0.7228
5  0.0736

# 可视化分箱
> plot(aa,col=d3$cluster)

5组聚类的结果。

每一种方法,对于分箱的离散化的结果都是不同的,使用哪一种方法,最好都有业务上的解释,不能随便乱用。

3. 有监督的数据离散化方法

有监督的离散化的方法,可以用R语言中discretization包来操作。discretization包,是一个用来做有监督离散化的工具集,主要用于卡方分箱算法,它提供了几种常用的离散化工具函数,可以按照自上而下或自下而上,实施离散化算法。

项目主页:https://cran.r-project.org/web/packages/discretization/

安装discretization包是非常简单的,只需要一条命令。


~ R
> install.packages("discretization")
> library(discretization)

discretization提供了几个主要的离散化的工具函数:

  • chiM,ChiM算法进行离散化
  • chi2, Chi2算法进行离散化
  • mdlp,最小描述长度原理(MDLP)进行离散化
  • modChi2,改进的Chi2方法离散数值属性
  • disc.Topdown,自上而下的离散化
  • extendChi2,扩展Chi2算法离散数值属性

3.1 卡方分箱

卡方分箱是依赖于卡方检验的分箱方法,在统计指标上选择卡方统计量(chi-Square)进行判别。卡方分箱的基本思想是判断相邻的两个区间是否有分布差异,如果两个相邻的区间具有非常类似的分布,则这两个区间可以合并;否则,它们应当保持分开。基于卡方统计量的结果进行自下而上的合并,直到满足分箱的限制条件为止。

卡方分箱的实现步骤:

1. 预先设定一个卡方的阈值。以这个阈值为标准,我们对数据进行卡方检验,通过显著性水平和自由度,计算出数据的卡方值与这个阈值进行比较。

  • 显著性水平,当置信度90%时显著性水平为10%,ChiMerge算法推荐使用置信度为0.90、0.95、0.99。
  • 自由度,比分类数量小1。例如:有3类,自由度为2。

类别和属性独立时,有90%的可能性,计算得到的卡方值会小于4.6。大于阈值4.6的卡方值就说明属性和类不是相互独立的,不能合并。如果阈值选的大,区间合并就会进行很多次,离散后的区间数量少、区间大。

2. 初始化:根据要离散化的数据对实例进行排序,每个实例属于一个区间
3. 合并区间:
1) 计算每一个对相邻区间的卡方值
2) 将卡方值最小的一对区间合并

卡方统计量衡量了区间内样本的频数分布与整体样本的频数分布的差异性,在做分箱处理时可以使用两种限制条件:

  • 分箱个数:限制最终的分箱个数结果,每次将样本中具有最小卡方值的区间与相邻的最小卡方区间进行合并,直到分箱个数达到限制条件为止。
  • 卡方阈值:根据自由度和显著性水平得到对应的卡方阈值,如果分箱的各区间最小卡方值小于卡方阈值,则继续合并,直到最小卡方值超过设定阈值为止。

4.评估指标

分为箱之后需要评估,常用的评估手段是计算出WOE和IV值。对于WOE和IV值的含义,参考文章:https://blog.csdn.net/kevin7658/article/details/50780391

3.2 数据准备

有监督的离散化算法,只少需要数据为2列,一列用于离散化的向量数据,一列是分类的评价标准数据,所以我们需要重新选择一个数据集,具有分类标准的数据。

我们使用一个系统自带的数据集iris,这个着名的Fisher的鸢尾花数据。iris包含150个记录,和5个变量的数据框,名为Sepal.Length(萼片的长度),Sepal.Width(萼片的宽度),Petal.Length(花瓣的长度),Petal.Width(花瓣的长度)和Species(种类,setosa,versicolor和virginica)。

查看数据集


> data(iris)
> head(iris,10)
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           5.1         3.5          1.4         0.2  setosa
2           4.9         3.0          1.4         0.2  setosa
3           4.7         3.2          1.3         0.2  setosa
4           4.6         3.1          1.5         0.2  setosa
5           5.0         3.6          1.4         0.2  setosa
6           5.4         3.9          1.7         0.4  setosa
7           4.6         3.4          1.4         0.3  setosa
8           5.0         3.4          1.5         0.2  setosa
9           4.4         2.9          1.4         0.2  setosa
10          4.9         3.1          1.5         0.1  setosa

接下来,我们分别用不同的算法,把这个数据集进行离散化处理。

3.3 chiM算法进行离散化

ChiM()函数,使用ChiMerge算法基于卡方检验进行自下而上的合并。通过卡方检验判断相邻阈值的相对类频率,是否有明显不同,或者它们是否足够相似,从而合并为一个区间。

chiM(data,alpha)函数解读。

  • 第一个参数data,是输入数据集,要求最后一列是分类属性。
  • 第二个参数alpha,表示显著性水平。
  • 自由度,通过数据计算获得是2,一共3个分类减去1。

下面使用chiM()进行计算。


# 离散化计算
> chi1<-chiM(iris,alpha=0.05)

# 查看前10条结果
> head(chi1$Disc.data,10)
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1             1           3            1           1  setosa
2             1           2            1           1  setosa
3             1           2            1           1  setosa
4             1           2            1           1  setosa
5             1           3            1           1  setosa
6             1           3            1           1  setosa
7             1           3            1           1  setosa
8             1           3            1           1  setosa
9             1           1            1           1  setosa
10            1           2            1           1  setosa

chi2算法的结果解读,从输出结果可以看出,Sepal.Length Sepal.Width Petal.Length Petal.Width,这几个变量被自动地离散化处理了。

查看这4个列的离散化情况。


> apply(chi1$Disc.data,2,table)
$Sepal.Length
 1  2  3  4 
52 21 65 12 

$Sepal.Width
 1  2  3 
57 56 37 

$Petal.Length
 1  2  3  4 
50 45 21 34 

$Petal.Width
 1  2  3 
50 54 46 

$Species
    setosa versicolor  virginica 
        50         50         50 

再查看每个列的阈值。


# 查看分组阈值
> chi1$cutp
[[1]]
[1] 5.45 5.75 7.05

[[2]]
[1] 2.95 3.35

[[3]]
[1] 2.45 4.75 5.15

[[4]]
[1] 0.80 1.75

以第一组Sepal.Length举例,被分为4类,当源数据Sepal.Length列的值,小于 5.45值为1类,大于5.45同时小于5.75为2类,大于5.75同时小于7.05为3类,大于7.05为4类。

我们把离散化后的数据,与源数据进行合并进行观察。第一列是离散化后的数据,第二列是源数据。


> chi1df<-cbind(chi1$Disc.data$Sepal.Length,iris$Sepal.Length)
> head(chi1df,20)
      [,1] [,2]
 [1,]    1  5.1
 [2,]    1  4.9
 [3,]    1  4.7
 [4,]    1  4.6
 [5,]    1  5.0
 [6,]    1  5.4
 [7,]    1  4.6
 [8,]    1  5.0
 [9,]    1  4.4
[10,]    1  4.9
[11,]    1  5.4
[12,]    1  4.8
[13,]    1  4.8
[14,]    1  4.3
[15,]    3  5.8
[16,]    2  5.7
[17,]    1  5.4
[18,]    1  5.1
[19,]    2  5.7
[20,]    1  5.1

这样就完成了卡方分箱的操作,接下来的其他几个函数的使用,与chiM()的算法类似,就不再过多讨论了。

3.4 其他算法

chi2()算法,查看分组阈值。


> chi2<-chi2(iris,alp=0.5,del=0.05)
> chi2$cutp
[[1]]
[1] 3.5 4.5 6.5

[[2]]
[1] 3.5 4.5

[[3]]
[1] 1.5 2.5 3.5

[[4]]
[1] 1.5 3.5

modChi2()算法,查看分组阈值。


> chi3<-modChi2(iris,alp=0.5)
> chi3$cutp
[[1]]
[1] 1.5 2.5

[[2]]
[1] 2.5

[[3]]
[1] 1.5 2.5

[[4]]
[1] 1.5 2.5

extendChi2()算法,查看分组阈值。


> chi4<-extendChi2(iris,alp = 0.5)
> chi4$cutp
[[1]]
[1] 1.5 2.5

[[2]]
[1] 1.5 2.5

[[3]]
[1] 1.5 2.5

[[4]]
[1] 1.5 2.5

> m1<-mdlp(iris)
> m1$cutp
[[1]]
[1] 5.55 6.15

[[2]]
[1] 2.95 3.35

[[3]]
[1] 2.45 4.75

[[4]]
[1] 0.80 1.75

disc.Topdown()算法,查看分组阈值。


> d1<-disc.Topdown(iris,method=1)
> d1$cutp
[[1]]
[1] 4.30 5.55 6.25 7.90

[[2]]
[1] 2.00 2.95 3.05 4.40

[[3]]
[1] 1.00 2.45 4.75 6.90

[[4]]
[1] 0.10 0.80 1.75 2.50

最后,分箱需要注意的是,分完箱之后,某些箱区间里可能数据分布比例极不均匀,那么这样子会直接导致后续计算WOE时出现inf无穷大的情况,这是不合理的。这种情况,说明分箱太细,需要进一步缩小分箱的数量。

本文详细地介绍了无监督的离散化方法和有监督的离散化方法,针对不同的场景,我们可以选择不同的方法进行使用。R语言中,包提供了各种离散化的工具函数,使用起来很方便,可以大幅提供数据处理过程的效率。

转载请注明出处:
http://blog.fens.me/r-discretization

打赏作者

HiBlock社区:区块链链上数据的认知与探索

跨界知识聚会系列文章,“知识是用来分享和传承的”,各种会议、论坛、沙龙都是分享知识的绝佳场所。我也有幸作为演讲嘉宾参加了一些国内的大型会议,向大家展示我所做的一些成果。从听众到演讲感觉是不一样的,把知识分享出来,你才能收获更多。

关于作者

  • 张丹(Conan), 程序员/Quant: Java,R,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/meeting-hiblock-20180826

前言

数字货币百花齐放,数字货币开发是区块链开发者的必修课也是入门课,通过ERC20智能合约很快就可以掌握开发技巧,但数字货币的安全如何保障?数字货币交易过程中产生了大量的数据,资金流转规律、操盘方式、筹码分布等等,通过数据预测数字货币价格走势也不是没有可能,除此之外区块链产生的数据还有什么价值?

本次的沙龙2个主题,一个是安全,一个是数据。

目录

  1. 我的演讲主题:区块链链上数据的认知与探索
  2. 会议体验和照片分享

1. 我的演讲主题:区块链链上数据的认知与探索

本次的沙龙2个主题,一个是安全,一个是数据,都是技术流!!所以,来听的也都是技术流,很少人,但很聊的来。

我本次分享的主题为:区块链链上数据的认知与探索,PPT下载,主要内容来自我的1篇博客文篇:区块链链上数据的认知与探索(未发布)。

分享主题的目录大纲如下:

  1. 认识区块链
  2. 区块浏览器
  3. 链上数据探索

主题简介:区块链上所有的交易都是公开透明的,链上账本会记录所有参与者交易行为,包括资金流转规律,庄家操盘,筹码分布等,价值巨大,从数据科学的角度,分享对区块链链上数据进行的认知与探索。

本此分析主要是从数据的角度切入,开始先介绍区块链,让大家有所认知;然后介绍区块链有什么样的数据,区别场内数据和场外数据;最后引出主题,对场外数据进行数据探索,通过账本的交易流水发现这些数据中的规律性的行为,坐庄行为,散户行为,拉盘行为….

数据是很有意思的,希望大家能够了解链上数据,用技术的武器去发现和鉴别真实的交易。

2. 会议体验和照片分享

本次线下沙龙的核心主题为,技术维度解读数字货币安全与数据价值,会议的主页:http://www.huodongxing.com/event/3453087067011

30人的小沙龙,定位就是区块链的技术圈,同业交流。我的分享是 “区块链链上数据的认知与探索” 也是在我这次转型积累的新的经验,跨学科的知识结合,从数据的角度理解区块链。

会议主题:

  • 14:00-14:05 开场 主办方介绍
  • 14:05-14:30 参会者自我介绍
  • 14:30-15:30《智能合约审计》分享嘉宾:赵威
  • 15:30-16:30《区块链链上数据的认知与探索》分享嘉宾:张丹
  • 16:30-17:00 合影 交流

我的介绍和照片分享。

分布式科技CTO,《R的极客理想-量化投资篇》作者,微软MVP。10年编程经验,获得10项SUN及IBM技术认证。前民生银行大数据分析师。个人博客 http://fens.me, Alexa全球排名70K。

2.2 会议相关照片

本次的场地在北京朝阳区建国路89号华贸商务楼16号B1 联合创业办公社,看上去更像是一个活动吧。

主持人:成芳

张丹,区块链链上数据的认知与探索

赵威, 智能合约审计

会后交流

政策条文: 分享开始前特意被关照,只能讲技术,不要讲其他的,最近太敏感,可能随时会被叫停!我们搞技术的人,底线是一定不会触碰的!!

布置会场。

大合照

主办方的小伙伴很辛苦,就一个小姑娘!坚持支持分享,保持高质量,坚持!坚持!

转载请注明出处:
http://blog.fens.me/meeting-hiblock-20180826

打赏作者

Ropsten测试网络部署自己的Token

比特币吸金之道系列文章,由计算机黑客发明的网络货币,无国界,无政府,无中心。没有政府滥发货币,没有通货膨胀。在全球计算机网络中,自由的实现货币兑换和流通。

本系列文章只讲程序和策略,不谈挖矿…

关于作者:

  • 张丹(Conan), 程序员/Quant: Java,R,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/bitcoin-eth-ropsten-token

前言

2017年,不断出现各种ICO项目,大量的币其实都是基于以太坊的公链,包装一个智能合约,远看很高深,近看很简单。以太坊作为区块链2.0时代的奠基者,功不可没,确实极大程度上推动了数字货币的兴起。

作为一个程序员,要关注新的领域和新的技术,区块链就是需要了解的一个新领域。自己把发币流程操作一遍,会有新的感悟。Ropsten是一个以太坊的测试网络,我们在这个网络进行发币实验。

目录

  1. 以太坊上发token
  2. 完成转账交易

1. 以太坊上发token

基于以太坊的公链发币,真的不难!工具已经被高度自动化地集成了,唯一花时间的事情,就是我们了解发token的操作原理。那么接下来,就让我们开始发token吧。

直接在正式的以太坊网络发币是要花钱的,我们先在测试网络上,把这个流程跑一遍,之后再用正式网络进行发币。

在以太坊上发token,操作步骤有如下几步进行:

  1. 打开VPN,建立国际访问通道。
  2. 打开Chrome浏览器,安装MetaMask插件
  3. 在MetaMask中,切换到Ropsten Test Network,并创建钱包
  4. 从测试网络中,获得测试的eth。
  5. 打开Remix 在线合约编程环境
  6. 编写 solidity 智能合约代码
  7. 编译,配置,提交ABI到测试网络
  8. 切换到 MetaMask 进行付费
  9. 生成合约,发币成功。

我们开始具体执行每个步骤的操作:

1.1 打开VPN,建立国际访问通道。

程序员都知道,不多说了。VPN服务器搭建,请参考文章在Ubuntu上安装IPSEC VPN服务在Ubuntu上安装PPTP VPN服务

1.2 打开Chrome浏览器,安装MetaMask插件。

安装好后,启用插件就行了,在chrome浏览器右上角会出现的一个小狐狸的图标。

1.3 在MetaMask中,切换到Ropsten Test Network,并创建钱包

打开MetaMask钱包,进行注册和登录。

然后,从 Main Ethereum Network 切换到测试网络 Ropsten Test Network 连接成功。

1.4 从测试网络中,获得测试的eth。

由于发token是需要进行付费(Gas),我们要先从测试网络中获得ETH。在MetaMask中,点击buy,就会弹出一个新的网页,用于获得测试网络中的token。点击faucet栏目下面的,request 1 eth from faucet的按钮,申请ETH。在user栏目中,会自动匹配我们的钱包地址(address)和余额(balnacen)。

在最下面transcation栏目中,会产生一笔ETH的转账信息,从faucet测试网络中,生成一笔转账到我们自己的钱包中。同时,我们可以查看这笔的完整转账信息。

我们多点几次,在钱包中就会获得多个ETH,现在我们钱包就4个ETH了,就可以用来付发币的费用了。

1.5 打开Remix 在线合约编程环境

Remix是一个在线的以太合约的编程环境,https://remix.ethereum.org/

Remix分为4个部分:

  • 文件管理:用于管理文件结构
  • 代码编写:是一个编辑器,用于编写 solidity 代码
  • 日志输入:运行可以后,用打印出运行日志
  • 命令控制:支持各种命令,如 编译,运行,发布等

1.6 编写 solidity 智能合约代码

我们可以定义一个自己的智能合约,如果不熟悉,可以找到一个已经发币的合约的例子,基于他合约代码的改一下。从etherscan上找一个合约。

复制它的代码,然后改一下名字。:-) (这种做法仅限于测试用,你不知道他的合约中有没有什么漏洞,所以最好还是仔细读读代码)


// Abstract contract for the full ERC 20 Token standard
// https://github.com/ethereum/EIPs/issues/20
pragma solidity ^0.4.23;

contract Token {

    uint256 public totalSupply;  // 供给总量
    function balanceOf(address _owner) public constant returns (uint256 balance);
    function transfer(address _to, uint256 _value) public returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) public returns (bool success);
    function approve(address _spender, uint256 _value) public returns (bool success);
    function allowance(address _owner, address _spender) public constant returns (uint256 remaining);
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

library SafeMath { // 安全计算函数
  function add(uint256 a, uint256 b) internal constant returns (uint256) {
    uint256 c = a + b;
    assert(c>=a && c>=b);
    return c;
  }
}

// 省略

contract FENS is StandardToken { // 符合ERC20标准

    function () public {
        revert();
    }

    using SafeMath for uint256;
    string public name = "fens.me Token";  
    uint8 public decimals = 18;
    string public symbol = "FENS";

// 省略

在代码中,contract FENS is StandardToken 这里,定义自己的合约的名字,叫FENS,同时简称symbol叫FENS。基于以太坊普遍要求遵守的规律,都符合ERC20的标准,有统一的命名规范,使用一致的变量和函数等,方便之后的交易所或钱包等其他应用的接入。

1.7 编译,配置,提交ABI到测试网络

接下来,通过reminx的命令控制的操作界面,进行是代码编译,做配置定义总发行量,然后生成ABI(Application Binary Interface)文件,用于部署到以太坊网络中。

按照上图所示,从左到右的操作顺序。

右1图,写完代码后,使用Compile标签中,点击start to compile进行代码编译,如果有错误,会直接显示错误信息。

在2图,编译完成后,切换到Run标签,看到Account对应的地址为,MetaMask中钱包的地址,这个插件让操作变得方便。FENS下拉框,显示的是这个Token的名字,在Deploy右边有一个文本框,是需要我们设置总供给量的,我在这个填入1,000,000,000,那么Token的总发行量为1亿。点击Deploy按钮,进行程序部署。

在3图,切换到 MetaMask会提示付费,这是由于我们使用ETH的网络,每一次的操作对应底层操作来说,是会经过矿工打包和确认的过程,所以不管是新发token还是转账,都是需要给矿工支付一定费用的。这里我自己输入5 GWei,以目前我的ETH市场价,这个大约值7.85USD。因为是在测试网络,所以多点少点,都无所谓啦。然后点击SUMBIT,确认支付,矿工进行打包。

在Remix的日志界面,就出现程序进行打包的日志。

1.8 生成合约,发币成功。

通过上面的链接,我们查看在以太坊测试网络中的执行情况,生成合约地址为:0xc6b08f0d67948854dff544b2093ccf726b7b17fd”

回到MetaMask界面,选择 ADD TOKEN 把刚才的生成的合约地址加入到当前创建者的钱包中,这样在钱包中就会出现已生成的token。

同时,我们也可以在以太坊的测试网络中,查到这个token的情况,0xc6b08f0d67948854dff544b2093ccf726b7b17fd”

这样就实现了,合约生成,完成了发token的整理流程。

2. 转账交易

接下来,我们就是发刚刚发的FENS代币,进行转账,转给别人的账户。由于MetaMask没有太多的转账功能,那么还需要使用一个在线转账的工具myetherwallet,用来完成转账的操作。

导出私钥 & 新建钱包

  • Account1 钱包地址:0xbA390993F3Ee624528c7EE9F280e2656613c7A81
  • Account2 钱包地址:0x35C8aEC449a8dE933C2d4beEFCc4490933F9f122

在myetherwallet,选择Network Repsten(infura.io)测试网络上进行注册和登录

选择 Send Ether & Tokens 的标签,通过私钥的方式导入账户。

接下来进行转账,输入Account2的钱包地址,和转账数量,选择FENS的代币,并设置Gas的消耗。

网页上,会弹出查看交易确认的选项。点击Yes,就开始进行交易。

完成进行交易确认后,查看2个账户的信息,FENS币,Account1账户少了50000币,Account2账户中多的50000个币。

我们可以通过以太坊网络,找到这条确认的消息。

发Token听起来很Cool,其实操作一遍还是觉得很Cool。你要不要自己也来发个Token?新的视角和新的思考方式,一起迎接新的挑战吧。

转载请注明出处:
http://blog.fens.me/bitcoin-eth-ropsten-token

打赏作者

2018Finance-AI社区:区块链链上数据的认知与探索

跨界知识聚会系列文章,“知识是用来分享和传承的”,各种会议、论坛、沙龙都是分享知识的绝佳场所。我也有幸作为演讲嘉宾参加了一些国内的大型会议,向大家展示我所做的一些成果。从听众到演讲感觉是不一样的,把知识分享出来,你才能收获更多。

关于作者

  • 张丹(Conan), 程序员/Quant: Java,R,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/meeting-financeai-20180614

前言

第一次在公开场合分享区块链,是一个好的开始。2017底到现在,中国经济在去杠杠,又要打贸易战,P2P各种爆仓,银行缩表,房市限购,人民币对美元大幅贬值,各种事情都在给这个浮躁的社会降温。

区块链的世界却是一片火热,各种人都在炒作概念,搞搞投机。数据,可以说是区块链里最能落地的事情,公链上记录的账本数据,对所有人都是公开的,数据之间藏着大量地真实的交易行业为,是数据学科家最好的探索的素材。

目录

  1. 我的演讲主题:区块链链上数据的认知与探索
  2. 会议体验和照片分享

1. 我的演讲主题:区块链链上数据的认知与探索

首先,感谢主办方的Aislinn的邀请。我本次分享的主题为:区块链链上数据的认知与探索,PPT下载,主要内容来自我的1篇博客文篇:区块链链上数据的认知与探索(未发布)。

分享主题的目录大纲如下:

  1. 认识区块链
  2. 区块浏览器
  3. 链上数据探索

主题简介:区块链上所有的交易都是公开透明的,链上账本会记录所有参与者交易行为,包括资金流转规律,庄家操盘,筹码分布等,价值巨大,从数据科学的角度,分享对区块链链上数据进行的认知与探索。

本此分析主要是从数据的角度切入,开始先介绍区块链,让大家有所认知;然后介绍区块链有什么样的数据,区别场内数据和场外数据;最后引出主题,对场外数据进行数据探索,通过账本的交易流水发现这些数据中的规律性的行为,坐庄行为,散户行为,拉盘行为….

数据是很有意思的,希望大家能够了解链上数据,用技术的武器去发现和鉴别真实的交易。

2. 会议体验和照片分享

本次线下沙龙的核心主题为“突围”,在AI时代,我们如何进行突围,会议的主页:http://www.huodongxing.com/event/7448082509300?td=7742536708807

120人的小沙龙,有5500多人浏览和193个收藏,不得不说主办方的组织能力。同时也能看出,本次的主题定位,就是当下时代大家最关心的话题。我的分享是 “区块链链上数据的认知与探索” 也是在我这次转型积累的新的经验,跨学科的知识结合,迎接AI时代。

会议主题:

  • Finance·AI社区金融算法介绍 Aislinn
  • 主题分享《大牛组团的年代,怎么做才能突围》 Kevin
  • 深度对话 《AI时代个人成长迭代之路 》 Aislinn对话Kevin
  • 主题分享 《区块链链上数据的认知与探索》 张丹
  • 主题分享 《知识图谱在金融风控中的应用》 邵平
  • 圆桌论坛 《金融算法职场与精进》Aislinn对话邵平和张丹
  • 金融算法社区学习计划 Aislinn

我的介绍和照片分享。

分布式科技CTO,《R的极客理想-量化投资篇》作者,微软MVP。10年编程经验,获得10项SUN及IBM技术认证。前民生银行大数据分析师。个人博客 http://fens.me, Alexa全球排名70K。

2.2 会议相关照片

本次的场地在 在(北京朝阳)云享客 · 长富宫中心(建国门外大街26号5号楼一层),一个很适合活动聚会的咖啡厅。

kevin的分享:大牛组团的年代,怎么做才能突围

邵平的分享:知识图谱在金融风控中的应用

现场的同学们。

布置会场。

茶点,小吃。

主办方的小伙伴辛苦啦!!获得嘉宾和听众的一致好评!继续高质量坚持!

转载请注明出处:
http://blog.fens.me/meeting-financeai-20180614

打赏作者

Truffle以太坊DApp开发框架

比特币吸金之道系列文章,由计算机黑客发明的网络货币,无国界,无政府,无中心。没有政府滥发货币,没有通货膨胀。在全球计算机网络中,自由的实现货币兑换和流通。

本系列文章只讲程序和策略,不谈挖矿…

关于作者:

  • 张丹(Conan), 程序员/Quant: Java,R,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/bitcoin-eth-truffle

前言

区块链的开发对于大多数的人来说,都是一件很新、很难的事情,有太多不一样的技术要学习。区块链有自己的设计理念,不同于传统分布式系统架构,数据同步机制,共识算法等。以太坊作为区块链2.0的产品,最独特是智能合约的设计,是超脱于技术的思维体系。

通过 Truffle 把这些不同的理念和思路进行整合,转换为开发人员能明白的一种编程方法。本文中的所有源代码已经上传到github,请有需要的同学下载使用: https://github.com/bsspirit/truffle-demo

目录

  1. Truffle安装
  2. 初始化项目
  3. 启动测试节点
  4. 部署合约
  5. 自定义的智能合约
  6. 交互的控制台
  7. 启动合约服务

1. Truffle安装

Truffle是Dapp开发框架,他可以帮我们处理掉大量无关紧要的小事情,让我们可以迅速开始写代码-编译-部署-测试-打包DApp这个流程。Truffle是使用Nodejs开发的,我们首先需要安装Nodejs运行环境。关于Nodejs的详细使用,请参考系列文章从零开始nodejs系列文章

DApp是什么?

App我们都知道是客户端应用,DApp就是D+App,D是英文单词decentralization的缩写,即DApp为去中心化应用。

检查操作系统版本和Nodejs版本。


> cat /etc/issue
Ubuntu 16.04 LTS \n \l

# Nodejs版本
> npm -v
6.0.0
> node -v
v8.9.4

全局安装Truffle工具。


# 安装truffle工具
> npm install -g truffle
/usr/local/bin/truffle -> /usr/local/lib/node_modules/truffle/build/cli.bundled.js
+ truffle@4.1.12
added 81 packages from 309 contributors in 2.571s

查看命令行帮助


> truffle
Truffle v4.1.12 - a development framework for Ethereum

Usage: truffle  [options]

Commands:
  init      Initialize new and empty Ethereum project
  compile   Compile contract source files
  migrate   Run migrations to deploy contracts
  deploy    (alias for migrate)
  build     Execute build pipeline (if configuration present)
  test      Run JavaScript and Solidity tests
  debug     Interactively debug any transaction on the blockchain (experimental)
  opcode    Print the compiled opcodes for a given contract
  console   Run a console with contract abstractions and commands available
  develop   Open a console with a local development blockchain
  create    Helper to create new contracts, migrations and tests
  install   Install a package from the Ethereum Package Registry
  publish   Publish a package to the Ethereum Package Registry
  networks  Show addresses for deployed contracts on each network
  watch     Watch filesystem for changes and rebuild the project automatically
  serve     Serve the build directory on localhost and watch for changes
  exec      Execute a JS module within this Truffle environment
  unbox     Download a Truffle Box, a pre-built Truffle project
  version   Show version number and exit

See more at http://truffleframework.com/docs

2. 初始化项目

新建工程目录,然后用truffle初始化项目。


> cd /root/workspace
> mkdir truffle01
> cd truffle01/

# 初始化项目
> truffle init
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

  Compile:        truffle compile
  Migrate:        truffle migrate
  Test contracts: truffle test

查看项目目录,目录下会生成下面的文件和目录。


> tree
.
├── contracts
│   └── Migrations.sol
├── migrations
│   └── 1_initial_migration.js
├── test
├── truffle-config.js
└── truffle.js
  • contracts/ , Truffle默认的合约文件存放地址。
  • migrations/ , 存放发布脚本文件
  • test/ , 用来测试应用和合约的测试文件
  • truffle-config.js, 配置文件
  • truffle.js, 配置文件

在contracts目录下,默认生成了一个合约文件Migrations.sol,执行编译合约。


> truffle compile
Compiling ./contracts/Migrations.sol...
Writing artifacts to ./build/contracts

成功编译后,会在build/contracts目录下,生成对于合约的Migrations.json文件,这个JSON就是

3. 启动测试节点

接下来,我们用testrpc搭建一个本地的简单的测试网络,相当于是一个mock,这样操作比较直接接入以太坊网络环境要容易的多。

安装测试网络工具testrpc


# 安装testrpc工具
> npm install -g ethereumjs-testrpc
npm WARN deprecated ethereumjs-testrpc@6.0.3: ethereumjs-testrpc has been renamed to ganache-cli, please use this package from now on.
/usr/local/bin/testrpc -> /usr/local/lib/node_modules/ethereumjs-testrpc/build/cli.node.js

> uglifyjs-webpack-plugin@0.4.6 postinstall /usr/local/lib/node_modules/ethereumjs-testrpc/node_modules/uglifyjs-webpack-plugin
> node lib/post_install.js

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules/ethereumjs-testrpc/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

+ ethereumjs-testrpc@6.0.3
added 339 packages from 279 contributors in 42.215s

启动testrpc测试网络。


> testrpc
EthereumJS TestRPC v6.0.3 (ganache-core: 2.0.2)

Available Accounts
==================
(0) 0x8dac051e949fdb323ff963f37de37345ac5a2de1
(1) 0x7ca2561b16a4181455537299ff766d4cec7cf6c3
(2) 0x7d1d40b9a015ff42d19cde1f95c0041ab1fac155
(3) 0x42730fd585a29029667274f0443ac0bb4830cb20
(4) 0xe3225679925b3790c850ec3560156aeff3fea1c2
(5) 0xd9f18fb4aa6ed92279136ddcdad73ad516fa7f7d
(6) 0xe9617966b21f20868a35d97e4abbb979f6b32431
(7) 0x15f1e3f6b1caa047281f91834530f14780b9adf7
(8) 0x53c049daad9338db54960e8620fefd3829590754
(9) 0xf6df046b0ce0d12bc978067bfcd0be209ee0b93c

Private Keys
==================
(0) 0c4cb520a02b1ea7c477e5ef028fef2da22be8589a08b5989fae5403c4fec21e
(1) 667adbcd821e183809bdf2d08cedbcd233741670cb61775ea491dd0ef862bf1f
(2) a5b0a337a7185544300f4d24e78b8a3f9d797280dc2ced40c7f3fe60ab943aa5
(3) 3e8f665924d45bcb013bff6111f3be557703ca0798ce824b14e84f5d7d2294e9
(4) 1620759f80e28a1258c18578253cade445d5d5e380a6fc12ed7cfe7e7f9ec408
(5) 60963d8c56c74d4f0cd460b7d9461581815153559ddb2eee9101eb3d2731fba9
(6) e20a5d21d0b6bdd88b143bedaab4ac94f7d1f2178236021b21991efea1ab6ee3
(7) d4d841c0430a9781bf86132db841364e92432d3c3d6ea25b5178e8a6d4c56984
(8) a98f4c3609d2c8e989a0f9bf86acdd4035bf0eac4de6b6c61545a8674f269b82
(9) d5ea07abc4cad2c9d26ebea32c67251ba7fcc3ab317739ec0a13a84cc1ccad47

HD Wallet
==================
Mnemonic:      enforce trust bridge guard memory stadium polar dignity provide alley embrace machine
Base HD Path:  m/44'/60'/0'/0/{account_index}

Listening on localhost:8545

这里生成了10个账号,和10个私钥,并模拟测试网络的打开了HTTP-RPC服务,这样就可以让智能合约的程序,基于这个测试网络进行开发了。

随着时间的,发现这个模拟的程序,还会自己模拟一些交易。


HD Wallet
==================
Mnemonic:      away lecture stuff weapon market spot infant solid capital monkey claw siege
Base HD Path:  m/44'/60'/0'/0/{account_index}

Listening on localhost:8545

eth_getBlockByNumber
eth_accounts
web3_clientVersion
net_version
eth_accounts
eth_accounts
eth_accounts
net_version
net_version
eth_sendTransaction

  Transaction: 0xd8e4638d4d2d95b2e2894fa724249cea81bdb539cf4c7b111dbefe0ea321b9eb
  Contract created: 0x0a2816a1c1ad71cda4843f57ab2c0a4a80cdfef9
  Gas usage: 277462
  Block Number: 1
  Block Time: Tue Jun 26 2018 18:49:33 GMT+0800 (CST)

eth_newBlockFilter
eth_getFilterChanges
eth_getTransactionReceipt
eth_getCode
eth_uninstallFilter
eth_sendTransaction

  Transaction: 0x27bda84efcb9a9677c17269919a00f01d7bd2c88b458bd20071c51e6e58dbd48
  Gas usage: 42008
  Block Number: 2
  Block Time: Tue Jun 26 2018 18:49:33 GMT+0800 (CST)

eth_getTransactionReceipt
eth_getBlockByNumber
eth_accounts
web3_clientVersion
eth_getBlockByNumber
eth_accounts
web3_clientVersion
eth_accounts

4. 部署合约

运行truffle migrate命令部署智能合约到测试网络上,第一次执行时出现错误Error: No network specified. Cannot determine current network,是因为没有连接到测试网络。

修改文件truffle.js,连接到测试网络上。


> vi truffle.js

module.exports = {
  networks: {
    development: {
      host: '127.0.0.1',
      port: 8545,
      network_id: '*'
    }
  }
};

再次启动truffle,完成部署的过程。


> truffle migrate
Using network 'development'.

Network up to date.

5. 自定义的智能合约

接下来,我们开始编写一个自己的智能合约,需要编写4个文件。

  • contracts/Hello.sol,合约文件
  • migrations/2_hello.js,部署文件
  • test/Hello.js,js单元测试文件
  • test/TestHello.sol,solidity单元测试文件

在contracts目录下,编写合约文件Hello.sol,提供2个函数,say()用来返回一个固定的字符串,sum()用来计算2个整书之和。


> vi ./contracts/Hello.sol

pragma solidity ^0.4.23;

contract Hello {

  function say() pure public returns (string) {
    return "Hello world";
  }


  function sum(uint a, uint b) pure public returns (uint val) {
    val = a + b ;
    return val;
  }

}

编写Hello.sol合约的部署脚本,放到migrations目录下面,文件名为2_hello.js。


> vi migrations/2_hello.js

var MyContract = artifacts.require("Hello");

module.exports = function(deployer) {
  deployer.deploy(MyContract);
};

单元测试有2种写法,一种是基于nodejs的Mocha库的写法,另一种是基本solidity的写法。

按Nodejs写法的测试用例,放到test目录下面,文件名为Hello.js。


> vi ./test/Hello.js

const Hello = artifacts.require("Hello");

contract('Hello test', async (accounts) => {

  it("say", async () => {
     let obj = await Hello.deployed();
     let val = await obj.say();
     assert.equal(val, "Hello world");
  })

  it("sum", async () => {
    let obj = await Hello.deployed();
    let val = await obj.sum(10,15);
    assert.equal(val, 25);

  });
})

按solidity写法的测试用例,放到test目录下面,文件名为TestHello.sol。


> vi ./test/TestHello.sol

pragma solidity ^0.4.24;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/Hello.sol";

contract TestHello {

  function test_say() public {
    Hello obj = Hello(DeployedAddresses.Hello());
    Assert.equal(obj.say(), "Hello world","test say");
  }

  function test_sum() public {
    Hello obj = Hello(DeployedAddresses.Hello());
    Assert.equal(obj.sum(10,15), 25, "test sum");
  }
}

编译Hello.sol合约,成功通过。


> truffle compile
Compiling ./contracts/Hello.sol...
Writing artifacts to ./build/contracts

把合约再次部署到testrpc的测试网络上面,这时需要用–reset参数。


> truffle migrate --reset
Using network 'development'.

Running migration: 1_initial_migration.js
  Replacing Migrations...
  ... 0x011256fee23fe4e633c86411f35e31f539e9026302495c3d824fca6b314ae92c
  Migrations: 0x298afbabd16ca14ec870377a61f983203ac69536
Saving successful migration to network...
  ... 0x59b23e1efc5f1bfb09af05ed3c26b7338573834394a61adea4bfc69775dcbae8
Saving artifacts...
Running migration: 2_hello.js
  Replacing Hello...                                                       # 创建合约
  ... 0x0aab9dd6c5781b899b60c7fc1190d3aefaa2af68363af386a8c473d40bc9f20f   # 交易hash
  Hello: 0x98ce096564f6b459b4a09b1b204ad6e362d384b6                        # 合约地址
Saving successful migration to network...
  ... 0x164b11ea951882cf5d374c2bdb979dac9586a87d0db4b8c6c8561d4cc7a9d5ca
Saving artifacts...

部署成功之后,我们可以看到testrpc的测试网络中,也有一些对应的更新。



eth_getTransactionReceipt
eth_accounts
eth_sendTransaction

  Transaction: 0x0aab9dd6c5781b899b60c7fc1190d3aefaa2af68363af386a8c473d40bc9f20f    # 交易hash
  Contract created: 0x98ce096564f6b459b4a09b1b204ad6e362d384b6                       # 合约地址
  Gas usage: 162663
  Block Number: 63
  Block Time: Wed Jun 27 2018 23:24:14 GMT+0800 (CST)

eth_newBlockFilter
eth_getFilterChanges
eth_getTransactionReceipt
eth_getCode
eth_uninstallFilter
eth_sendTransaction

  Transaction: 0x164b11ea951882cf5d374c2bdb979dac9586a87d0db4b8c6c8561d4cc7a9d5ca
  Gas usage: 27008
  Block Number: 64
  Block Time: Wed Jun 27 2018 23:24:14 GMT+0800 (CST)

eth_getTransactionReceipt

接下来,我们就是可以运行test的命令,来测试合约的正确性。


> truffle test
Using network 'development'.

Compiling ./contracts/Hello.sol...
Compiling ./test/TestHello.sol...
Compiling truffle/Assert.sol...
Compiling truffle/DeployedAddresses.sol...

  TestHello
    ✓ test_say (119ms)
    ✓ test_sum (70ms)

  Contract: Hello test
    ✓ say
    ✓ sum

  4 passing (1s)

2种写法的单元测试文件,都通过的测试。2种写法的区别在于,Nodejs当中是异步执行测试的,solidity是同步的。

Nodejs的优势是测试与前端测试相似,可以模拟前端测试,称为整合测试,可以有更强大的语法支持。js的另一大优势可以比较简单地实现异常捕捉。

solidity测试写法简洁,适用于单元测试,另一大优势是js只能测试public的函数,soli可以测试内部function,internal的,通过继承被测试contract来获得internal function的访问权限。

6. 交互的控制台

接下来,我们在网络执行合约,可以通过控制台的交互的命令来完成,启动控制台 truffle console。


> truffle console

# 执行合约函数
truffle(development)> var contract;
undefined
truffle(development)> Hello.deployed().then(function(instance){contract= instance;});
undefined
truffle(development)> contract.say()
'Hello world'
truffle(development)> contract.sum(1,21)
BigNumber { s: 1, e: 1, c: [ 22 ] }

# 查看合约地址
truffle(development)> Hello.address
'0x98ce096564f6b459b4a09b1b204ad6e362d384b6'

# 查看合约abi
truffle(development)> JSON.stringify(Hello.abi)
'[{"constant":true,"inputs":[],"name":"say","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"a","type":"uint256"},{"name":"b","type":"uint256"}],"name":"sum","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"}]'

7. 启动合约服务

最后,启动服务程序,开放一个HTTP的端口,允许通过Http访问JSON ABI(Application Binary Interface),ABC指定了合约接口,包括可调用的合约方法、变量、事件等。


> truffle serve
Serving static assets in ./build on port 8080...

启动truffle serve时,一直会有一个报错,TypeError: fsevents is not a constructor


> truffle serve
Serving static assets in ./build on port 8080...

/usr/local/lib/node_modules/truffle/build/webpack:/Users/gnidan/src/work/truffle/~/chokidar/lib/fsevents-handler.js:26
  return (new fsevents(path)).on('fsevent', callback).start();
^
TypeError: fsevents is not a constructor
    at createFSEventsInstance (/usr/local/lib/node_modules/truffle/build/webpack:/Users/gnidan/src/work/truffle/~/chokidar/lib/fsevents-handler.js:26:1)
    at setFSEventsListener (/usr/local/lib/node_modules/truffle/build/webpack:/Users/gnidan/src/work/truffle/~/chokidar/lib/fsevents-handler.js:80:1)
    at FSWatcher.FsEventsHandler._watchWithFsEvents (/usr/local/lib/node_modules/truffle/build/webpack:/Users/gnidan/src/work/truffle/~/chokidar/lib/fsevents-handler.js:244:1)
    at FSWatcher. (/usr/local/lib/node_modules/truffle/build/webpack:/Users/gnidan/src/work/truffle/~/chokidar/lib/fsevents-handler.js:378:1)
    at gotStat (fs.js:1775:21)
    at FSReqWrap.oncomplete (fs.js:152:21)

只有修改truffle的源代码文件中,把useFsEvents 检查项去掉就可以了。


> vi /usr/local/lib/node_modules/truffle/build/cli.bundled.js

// Enable fsevents on OS X when polling isn't explicitly enabled.
//if (undef('useFsEvents')) opts.useFsEvents = !opts.usePolling;

// If we can't use fsevents, ensure the options reflect it's disabled.
//if (!FsEventsHandler.canUse()) opts.useFsEvents = false;
opts.useFsEvents = false;

最后,用浏览器访问HTTP服务,http://103.211.167.71:8080/contracts/Hello.json

如下图所示:

总结一下,在本文中我们使用了trffule工具,完成了智能合约的 代码-编译-部署-测试-打包的完事流程,操作起来还是很方便的。

本文中的所有源代码已经上传到github,请有需要的同学下载使用: https://github.com/bsspirit/truffle-demo

接下来的步骤,就是把我们自定义的Hello.sol部署到Geth的私有网络中,等下篇文章再具体说明。Geth的私有网络环境搭建,请参考文章以太坊测试区块链环境搭建

转载请注明出处:
http://blog.fens.me/bitcoin-eth-truffle

打赏作者