知行合一

致良知


  • 首页

  • 归档

  • 站点地图

Ubuntu命令行设置ipfs开发环境

发表于 2018-06-04 |

部署一台Ubuntu服务器

设置科学上网,因为ipfs已被墙

购买科学上网服务,SSR服务,如bosXXX和rixXXXX,得到一堆ssr服务地址

部署Ubuntu SSR客户端

  1. 下载ssr客户端
1
2
3
4
5
wget https://onlyless.github.io/ssr
sudo mv ssr /usr/local/bin
sudo chmod 766 /usr/local/bin/ssr
ssr install
ssr config
  1. 配置ssr地址
1
2
3
4
5
6
7
8
{
"server" : "your serverip",
"server_port" : yourport,
"password" : "your password",
"method" : "your method",
"protocol" : "your protocol",
"obfs" : "your obfs",
}
  1. 重启
1
ssr restart
  1. 配置开机启动, vim /etc/rc.local
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

sudo ssr start
exit 0

安装Privoxy

  1. 因为ssr是sock5代理,不接受http/https流量,使用的时候需要将其转化成http/https流量

  2. 安装Privoxy

1
apt-get install privoxy
  1. 配置Privoxy,打开其配置文件/etc/privoxy/config,修改以下几个地方
  • 找到4.1. listen-address,确认privoxy监听的端口号
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
#  Example:
#
# Suppose you are running Privoxy on a machine which has the
# address 192.168.0.1 on your local private network
# (192.168.0.0) and has another outside connection with a
# different address. You want it to serve requests from inside
# only:
#
# listen-address 192.168.0.1:8118
#
# Suppose you are running Privoxy on an IPv6-capable machine and
# you want it to listen on the IPv6 address of the loopback
# device:
#
# listen-address [::1]:8118
#
listen-address localhost:8118
#
# 4.2. toggle
# ============
#
# Specifies:
#
# Initial state of "toggle" status
#
# Type of value:
#
# 1 or 0
#
# Default value:
  • 找到5.2. 设置sock5转发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#      Unencrypted connections to systems in these address ranges
# will be as (un)secure as the local network is, but the
# alternative is that you can't reach the local network through
# Privoxy at all. Of course this may actually be desired and
# there is no reason to make these exceptions if you aren't sure
# you need them.
#
# If you also want to be able to reach servers in your local
# network by using their names, you will need additional
# exceptions that look like this:
#
# forward localhost/ .
#
#
forward-socks5 / 127.0.0.1:1080 .
# 5.3. forwarded-connect-retries
# ===============================
#
# Specifies:
#
  1. 重启Privoxy
1
/etc/init.d/privoxy restart
  1. 编写两个bash脚本,start_proxy.sh,stop_proxy.sh;用source start_proxy.sh/stop_proxy.sh 来开启和关闭代理
1
2
3
4
5
6
# start_proxy.sh
export http_proxy="127.0.0.1:8118"
export https_proxy="127.0.0.1:8118"

git config --global http.proxy http://127.0.0.1:8118 # 可以用sock5://127.0.0.1:1008
git config --global https.proxy https://127.0.0.1:8118
1
2
3
4
5
6
# stop_proxy.sh
export http_proxy=
export https_proxy=

git config --global --unset http.proxy
git config --global --unset https.proxy
  1. 开始代理,测试是否可以穿墙
1
2
source start_proxy.sh
curl https://www.google.com # 测试

安装开发工具

  1. 安装工具 git
1
apt-get install git
  1. 安装golang
1
2
3
4
5
wget https://dl.google.com/go/go1.10.2.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.10.2.linux-amd64.tar.gz
ln -s /usr/local/go/bin/go /usr/local/go
ln -s /usr/local/go/bin/gofmt /usr/local/gofmt
ln -s /usr/local/go/bin/godoc /usr/local/godoc
  1. 创建一个golang工作目录,比如~/gopath,编辑.bashrc,在文件最后添加以下内容;确保.profile 会调用.bashrc
1
2
export GOPATH="$HOME/gopath"
export PATH="$GOPATH/bin:$PATH"

下载编译源码

  1. 下载源码。虽然已经翻墙,但也不能直接编译,原因是ipfs使用的包管理工具gx不支持http代理。
1
go get -u -d -v github.com/ipfs/go-ipfs
  1. 编译ipfs包管理工具GX

    1. 下载GX

      1
      2
      go get -u -v -d github.com/whyrusleeping/gx
      go get -u -v -d github.com/whyrusleeping/gx-go
    2. 修改 github.com/ipfs/go-ipfs-api/shell.go

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      func NewShell(url string) *Shell {
      c := &gohttp.Client{
      Transport: &gohttp.Transport{
      Proxy: gohttp.ProxyFromEnvironment, // 这里是添加的一行
      DisableKeepAlives: true,
      },
      }

      return NewShellWithClient(url, c)
      }
    3. 编译GX,编译完后可以在$(GOPATH)/bin目录找到gx和gx-go程序

      1
      2
      go install github.com/whyrusleeping/gx
      go install github.com/whyrusleeping/gx-go
  2. 用gx下载所有的依赖包

1
gx install --global
  1. 进入go-ipfs目录,编译ipfs,编译完后可以在$(GOPATH)/bin目录找到ipfs程序
1
make install

在docker中构建ubuntu开发环境

发表于 2018-05-19 |

环境

  1. 宿主机环境windows,从官网下载docker的windows版本,安装完毕后切换到Linux Containers
  2. 镜像使用ubuntu 16.04

docker三大概念

  1. 容器Container:相当于虚拟机
  2. 镜像Image:相当于虚拟机的iso
  3. 仓库Repository:相当于github,官网仓库是hub.docker.com

构建一个镜像,镜像的脚本默认名字为Dockerfile

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
FROM ubuntu:16.04

ENV LANG=en_US.UTF-8

RUN apt-get update -y

RUN apt-get -y install gcc \
g++ \
gdb \
automake \
autoconf \
libtool \
make \
cmake

RUN apt-get -y install ssh \
ntp \
vim \
wget \
curl \
telnet

RUN apt-get -y install git \
subversion \
doxygen \
lighttpd \
net-tools \
inetutils-ping

RUN apt-get -y install python \
golang

RUN apt-get -y install libbz2-dev \
libdb++-dev \
libssl-dev \
libdb-dev \
libssl-dev \
openssl \
libreadline-dev \
libcurl4-openssl-dev \
libncurses-dev \
autotools-dev \
build-essential \
libicu-dev \
python-dev

RUN mkdir /var/run/sshd

# change sshd listen port
RUN sed -i 's/Port[ ]*22/Port 36000/' /etc/ssh/sshd_config
RUN echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config

# add user
RUN mkdir /home/bingo
RUN useradd -s /bin/bash bingo
RUN echo "bingo:123456" | chpasswd
RUN echo "bingo:123456" | chpasswd
RUN chown -R bingo:bingo /home/bingo

# Container should expose ports.
EXPOSE 36000
CMD ["/usr/sbin/sshd", "-D"]

创建一个空目录,在其下建立一个名叫Dockerfile文件,输入以上内容

制作镜像

1
docker build -t ubuntu:dev.16.04 .

如果制作过程中出错,删除相关的命令,重新输入上面的命令继续制作

制作出来的镜像大小大概在960m左右,用”docker image ls”查看

启动容器

1
docker run -d --name dev-ubuntu -p 36000:36000 ubuntu:dev.16.04

-p 36000:36000 前面的36000为宿主机端口,后面为容器端口

docker启动的时候,需要把本容器也启动起来,带参数”–restart=always”

如果需要挂载本地磁盘,使用参数”-v /opt/projects:/home/bingo/“

docker端口映射等网络相关内容可以参考这篇文章

ssh登录到容器

1
ssh -p 36000 bingo@127.0.0.1

“127.0.0.1” 指宿主机的ip

-p 36000 指向宿主机的port

推到仓库,供以后重复使用

  1. 在 https://hub.docker.com/ 上创建一个账号

  2. 登录仓库

1
docker login

按提示输入账号密码

  1. 编译,指向自己的用户名username
1
docker build -t username/ubuntu:dev.16.04 .
  1. 发布到hub
1
docker image push username/ubuntu:dev.16.04

发布后,就可以在 https://hub.docker.com/ 看到刚发布的镜像文件了

  1. 下次需要的时候,就可以用以下命令拉取
1
docker image pull username/ubuntu:dev.16.04

bitshares-witness节点结构之入口

发表于 2018-05-11 |

入口分成三个部分

  • main函数入口

  • 主循环入口

  • 网络消息入口

main函数入口

  • 成员结构
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
34
35
36
37
38
39
40
main
1. app:application - 应用
1. map<string, app::abstract_plugin> - 所有插件, 分激活的和能够支持的
1. witness_plugin::witness_plugin - 见证人
1. witness private_keys - 见证人私钥
2. witness ids - 见证人ids
3. witness block schedule - 区块产生调度器
2. debug_witness_plugin::debug_witness_plugin - 见证人调试,监听区块链事件
3. account_history::account_history_plugin - 账号历史事件,监听区块链事件,并记录到object_database中
4. elasticsearch::elasticsearch_plugin - ES插件
5. market_history::market_history_plugin - 市场历史
6. delayed_node::delayed_node_plugin - 延时节点
7. snapshot_plugin::snapshot_plugin - 快照
8. es_objects::es_objects_plugin - ES对象
9. grouped_orders::grouped_orders_plugin - 命令组
2. chain::database - 区块链
1. object_database - 对象索引管理,chain::database继承自object_database
1. index[256][256] - 对象索引
1. index = primary_index<witness_index> - 以下为举例
1. witness_index = generic_index<witness_object, witness_multi_index_type>;
1. witness_object = multi_index_container<witness_object,
indexed_by<
ordered_unique< tag<by_id>,member<object, object_id_type, &object::id>>,
ordered_unique< tag<by_account>,member<witness_object, account_id_type, &witness_object::witness_account>>,
ordered_unique< tag<by_vote_id>,member<witness_object, vote_id_type, &witness_object::vote_id>>
> >;
2. block_database - 区块数据库
1. _blocks - 实际区块数据
2. _block_num_to_pos - 区块索引数据
3. net::node - p2p节点
4. websocket_server - ws连接,api再连接里面
5. websocket_tls_server - wss连接,api再连接里面
1. websocket_connection_ptr
1. websocket_api_connection
1. app::login_api
6. api_access - api接口控制
2. bpo::variables_map - 配置
1. bpo::options_description - 入口配置:argc,argv
2. bpo::options_description - 文件配置:data/config.ini
3. exit signal - 退出信号
  • 启动顺序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
main
1. app:register_plugin<>*9 - 注册9个插件
2. app_options:read - 读取入口函数配置参数
3. cfg_options:read - 读取配置文件参数
4. app:initialize - 初始化
5. app:initialize_plugins - 初始化插件
6. app:startup - 启动
1. chain::database:open - 启动区块链
1. db version check - 链版本检查
2. object_database:open - 对象数据读取,对应本地的object_database目录
3. block_database::open - 区块数据读取,对应本地的database目录
4. init_genesis - 初始化创世数据
5. reindex - 索引检查
2. set allowed_apis - ws/wss等api权限设置
3. reset_p2p_node - 启动p2p网络
4. reset_websocket_server - 启动ws网络
5. reset_websocket_tls_server - 启动wss网络
7. app:startup_plugins - 启动插件
1. witness_plugin::plugin_startup - 启动witness插件
1. dschedule_production_loop - 启动区块产生的循环
1. witness_plugin::maybe_produce_block - 根据条件来确认是否产生区块
8. wait exit signal - 等待退出信息,如ctrl+c
9. app:shutdown_plugins - 关闭所有插件
10. app:shutdown - 关闭

主循环入口

  • 见证人插件,内部循环会调用函数,条件是node为见证人节点、时序轮到自己等

    • witness_plugin::maybe_produce_block
  • Delay节点插件,定时从见证人节点获取已经落地的数据

    • delayed_node_plugin::mainloop

网络消息入口

  • p2p网络消息接收点

    • 有20多个协议,但业务主要用到trx_message_type,其下面有47个操作类型,如transfer_operation,limit_order_create_operation,limit_order_cancel_operation等
    • application下的application_impl::handle_transaction 为trx_message_type类消息的接受点
    • 此消息的处理在witness_plugin::maybe_produce_block中
  • ws/wss, http/https网络消息接收点

    • login_api - websocket_api_connection 注册 login_api和database_api 接口
      • block_api
      • database_api - 默认
      • network_broadcast_api - 默认
      • network_node_api
      • history_api - 默认
      • crypto_api - 默认
      • asset_api
      • orders_api - 默认
      • graphene::debug_witness::debug_api

bitshares反射解析

发表于 2018-05-09 |
  • 反射,关键在理解宏BOOST_PP_SEQ_FOR_EACH,分成以下两类
    • 成员反射
      • 原理:生成一个reflector<T>类,把T的成员转移到reflector<T>中,并提供visit(visitor&)接口访问,访问的时候遍列每个成员,且调用visitor.operator(const char* name)
      • 应用
        • variant:即可以把T转移到variant中,也可以从variant转移出来
        • 序列化:pack、unpack
    • 接口反射
      • 原理:生成一个vtable<T,Transform>类,把T的成员函数转移到vtable<T,Transform>中,转移成成员,并提供visit(visitor&&)接口访问,访问的时候遍列每个成员,调用方法有两类,且都可以修改memb
        • visitor.operator()( const char* name, std::function<R(Args…)>& memb, MemberPtr m ),memb为成员,m为vistor的类的成员函数&OtherType::elem
        • visitor.operator()( const char* name, std::function<R(Args…)>& memb )
        • 使用:api<interfaceT> apit(realT),
          • 内部生成vtable<T,Transform>实例,使用api->访问vtable<T,Transform>的实例的“虚拟函数”
          • 构造的时候,会调用visitor.operator()( const char* name, std::function<R(Args…)>& memb, MemberPtr m ),接口的真实地址变更到realT上
      • 应用
        • 网络RCP调用,参数和返回值需要转化成variant

BTS UI钱包搭建以及接入到私有链

发表于 2018-05-09 |

参考地址

  • 参考文章-比特股钱包定制
  • 参考文章-官方帮助MD

安装环境

  • 系统ubuntu16.04
  • 检查是否已经安装nvm,没有则
1
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.2/install.sh | bash
  • 安装node
1
2
nvm install v6
nvm use v6

本地切换只针对当前命令行窗口有效,新打开命令行,需要重新切换v6

源码下载和安裝

  • 下载和安装依赖
1
2
3
git clone https://github.com/bitshares/bitshares-ui.git
cd bitshares-ui
npm install
  • 安装中如果遇到问题

    先安装cnpm

1
npm install -g cnpm --registry=https://registry.npm.taobao.org

然后用cnpm安装所有的包。如果只有”electron”和”electron-builder”无法下载,可暂时删除依赖。

  • 启动服务
1
npm start

成功的话,会看到以下提示

1
webpack: Compiled succeedfully.

浏览器中输入以下命令查看运行情况

1
http://localhost:8080

配置和源码修改

  • 替换掉所有的货币名,搜索所有代码替换,包括js和node_modules/bitsharesjs-ws
  • 修改node_modules/bitsharesjs-ws的chainid,路径node_modules/bitsharesjs-ws/es/src/ChainConfig.js和node_modules/bitsharesjs-ws/cjs/src/ChainConfig.js
  • 修改链的地址和水龙头地址,路径app\api\apiConfig.js
  • 修改交易对等,路径app\stores\SettingsStore.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let topMarkets = {
markets_4018d784: [ // BTS MAIN NET
"OPEN.MKR", "BTS", "OPEN.ETH", "ICOO", "BTC", "OPEN.LISK", "BKT",
"OPEN.STEEM", "OPEN.GAME", "OCT", "USD", "CNY", "BTSR", "OBITS",
"OPEN.DGD", "EUR", "GOLD", "SILVER", "IOU.CNY", "OPEN.DASH",
"OPEN.USDT", "OPEN.EURT", "OPEN.BTC", "CADASTRAL", "BLOCKPAY", "BTWTY",
"OPEN.INCNT", "KAPITAL", "OPEN.MAID", "OPEN.SBD", "OPEN.GRC", "YOURASSET",
"YOYOW", "HERO", "RUBLE"
],
markets_39f5e2ed: [ // TESTNET
"PEG.FAKEUSD", "YOURASSET", "BTWTY"
]
};

let bases = {
markets_4018d784: [ // BTS MAIN NET
"USD", "OPEN.BTC", "CNY", "BTS", "BTC", "YOURASSET"
],
markets_39f5e2ed: [ // TESTNET
"TEST", "YOURASSET"
]
};
1
2
3
4
5
6
7
8
9
10
        let defaults = {
unit: [
CORE_ASSET,
"USD",
"CNY",
"BTC",
"EUR",
"YOURASSET"
]
};

水龙头服务搭建

  • 参考搭建比特股的水龙头注册服务,写的很详细,最后总结了一些问题的处理办法

重装系统备忘

发表于 2018-05-03 |
  1. 系统安装
  • 使用win10企业版,激活使用DCPHK-NFMTC-H88MJ-PFHPY-QJ4BJ
  1. 软件安装
  • 通用工具

    • 百度网盘 同步文件
    • OneDrive 同步文件
    • QQ拼音 输入法
    • Chrome 浏览器,同步收藏夹等
    • ShadowsocksR-4.6.1-win 科学上网
    • 腾讯桌面管理 桌面管理和快速搜索
    • Colver 文件浏览器
    • winrar 压缩解压工具
    • notepad++ 文本工具
    • 有道笔记和有道翻译
  • 沟通软件

    • TIM
    • 微信
    • 钉钉
  • 办公软件

    • wps office
    • xmind
    • foxmail
  • 开发辅助工具

    • bcompare 对比工具
    • cmder 命令行工具
    • navicat for mysql mysql访问工具
    • mRemoteNG 远程工具
  • 开发语言和工具

    • git 版本管理工具
    • golang
    • python 2.7
    • cmake
    • vscode + 插件
    • vs2013 + VA + 其他插件

bitshares vs2013 x64位 编译

发表于 2018-05-02 |
  1. windows编译bitshares

    • 前提:安装好vs2013-update5、cmake、git工具、doxygen工具(非必须),环境变量PATH有对应的EXE
    • 目录结构

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      - D:\_workdir\source
      - bitshares
      - bitshares-core
      - dependencies
      - boost_1_57_0
      - source
      - openssl-1.0.1u
      - zlib-1.2.11
      - curl-7.59.0
      - bin
      - include
      - lib
      - ssl
    • 编译openssl

      • 下载安装activePerl,注意环境变量PATH
      • 下载安装nasm,注意环境变量PATH
      • 下载openssl源码,版本最好选择1.0.1,切勿选择大于1.0.2的版本
      • 打开vs2013 x64 本机工具命令提示,输入
        1
        2
        3
        4
        5
        cd D:\_workdir\source\dependencies\source\openssl-1.0.1u
        perl Configure VC-WIN64A --prefix=D:\_workdir\source\dependencies
        ms\do_win64a
        nmake -f ms\nt.mak
        nmake -f ms\nt.mak install
    • 编译zlib

      • 下载zlib源码,选择的是1.2.11版本
      • 打开“contrib\vstudio\vc12\zlibvc.sln”,选择release和x64进行编译
      • 编译成功后把“contrib\vstudio\vc12\x64\ZlibStatRelease\zlibstat.lib”复制到“dependencies\lib\zlib.lib”,把“D:_workdir\source\dependencies\source\zlib-1.2.11”的头文件“zlib.h、zconf.h”复制到“dependencies\include”目录
    • 编译curl

      • 下载curl源码,选择的是7.59.0版本
      • 打开vs2013 x64 本机工具命令提示,输入

        1
        2
        cd D:\_workdir\source\dependencies\source\curl-7.59.0\winbuild
        nmake /f Makefile.vc mode=static VC=12 WITH_DEVEL=D:\_workdir\source\dependencies WITH_SSL=static WITH_ZLIB=static MACHINE=x64
      • 编译成功后把“dependencies\source\curl-7.59.0\builds\libcurl-vc12-x64-release-static-ssl-static-zlib-static-ipv6-sspi”的所有目录copy到“dependencies”下,libcurl.lib更名为curl.lib

      • 修改curl.h头文件,在第109行加入

        1
        #define CURL_STATICLIB
    • 编译boost

      • 下载1.57版本
      • 打开vs2013 x64 本机工具命令提示,输入
        1
        2
        3
        cd D:\_workdir\source\dependencies\boost_1_57_0
        .\bootstrap.bat
        b2 stage --address-model=64 --toolset=msvc-12.0 --threading=muti --link=static
    • 编译bitshares

      • 下载源码,切换到最新版本。打开vs2013 x64 本机工具命令提示,输入

        1
        2
        3
        4
        5
        6
        cd D:\_workdir\source\bitshares
        git clone https://github.com/bitshares/bitshares-core
        cd bitshares-core
        git submodule update --init --recursive
        rem git checkout 2.0.180425
        rem 注释掉这句,这个版本缺少一个文件
      • 重启系统,确保以上的PATH都生效

      • 设置环境脚本setenv_x64.bat,放到bitshares-core目录

        1
        2
        3
        4
        5
        6
        7
        8
        @echo off

        set GRA_ROOT=D:\_workdir\source\bitshares\bitshares-core
        set OPENSSL_ROOT=D:\_workdir\source\dependencies
        set OPENSSL_ROOT_DIR=%OPENSSL_ROOT%
        set OPENSSL_INCLUDE_DIR=%OPENSSL_ROOT%\include
        set BOOST_ROOT=D:\_workdir\source\dependencies\boost_1_57_0
        set PATH=%BOOST_ROOT%\stage\lib;%PATH%
      • 为了兼容windows版本,进行相应修改,见以下内容

      • 打开vs2013 x64 本机工具命令提示,输入

        1
        2
        3
        cd D:\_workdir\source\bitshares\bitshares-core
        setenv_x64.bat
        cmake-gui
      • 配置cmake工程,

        • 设置source目录为:D:_workdir\source\bitshares\bitshares-core
        • 设置输出目录为:D:_workdir\source\bitshares\bitshares-core\x64
        • 点击Configure,在弹出框中,
          • 第一个下拉框 Specify the generator for this project 选 Visual Studio 12 2013 Win64
          • 第二个输入框 Optional toolset to use (argument to -T) 留空
          • 下面的单选框,选 Use default native compilers
        • 点 Finish ,然后等一会, Generate 按钮会亮起
        • 点 Generate ,然后等一会, Open Project 按钮会亮起
        • 点 Open Project ,会打开 Visual Studio
      • 开始编译,有可能遇到bigobj问题,再进行相应修改
  2. 为兼容windows版本,需对bitshares源码进行以下相关修改

    • bitshares源码修改

      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
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      diff --git a/CMakeLists.txt b/CMakeLists.txt
      index 5e91e80b..e11f4c20 100644
      --- a/CMakeLists.txt
      +++ b/CMakeLists.txt
      @@ -2,6 +2,10 @@
      project( BitShares )
      cmake_minimum_required( VERSION 2.8.12 )

      +if(POLICY CMP0054)
      + cmake_policy(SET CMP0054 NEW)
      +endif()
      +
      set( BLOCKCHAIN_NAME "BitShares" )

      set( CLI_CLIENT_EXECUTABLE_NAME graphene_client )
      diff --git a/libraries/chain/include/graphene/chain/protocol/fee_schedule.hpp b/libraries/chain/include/graphene/chain/protocol/fee_schedule.hpp
      index 2d381308..0d18e8b8 100644
      --- a/libraries/chain/include/graphene/chain/protocol/fee_schedule.hpp
      +++ b/libraries/chain/include/graphene/chain/protocol/fee_schedule.hpp
      @@ -54,7 +54,7 @@ namespace graphene { namespace chain {
      FC_ASSERT( itr != parameters.end() );
      return itr->get<account_create_operation::fee_parameters_type>();
      }
      - typename account_create_operation::fee_parameters_type& get(flat_set<fee_parameters>& parameters)const
      + account_create_operation::fee_parameters_type& get(flat_set<fee_parameters>& parameters)const
      {
      auto itr = parameters.find( account_create_operation::fee_parameters_type() );
      FC_ASSERT( itr != parameters.end() );
      diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp
      index b78bb835..a8a11023 100644
      --- a/tests/cli/main.cpp
      +++ b/tests/cli/main.cpp
      @@ -38,8 +38,12 @@
      #include <fc/rpc/websocket_api.hpp>
      #include <fc/rpc/cli.hpp>

      +#if defined _WINDOWS_ || defined WIN32
      +#include "winsock2.h"
      +#else
      #include <sys/socket.h>
      #include <netinet/ip.h>
      +#endif
      #include <sys/types.h>

      #include <boost/filesystem/path.hpp>
      @@ -109,9 +113,14 @@ int get_available_port()
      sin.sin_family = AF_INET;
      sin.sin_port = 0;
      sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
      - if (bind(socket_fd, (struct sockaddr*)&sin, sizeof(struct sockaddr_in)) == -1)
      + if (::bind(socket_fd, (struct sockaddr*)&sin, sizeof(struct sockaddr_in)) == -1)
      return -1;
      +
      +#if defined _WINDOWS_ || defined WIN32
      + int len = sizeof(sin);
      +#else
      socklen_t len = sizeof(sin);
      +#endif
      if (getsockname(socket_fd, (struct sockaddr *)&sin, &len) == -1)
      return -1;
      return sin.sin_port;
    • fc 源码修改

      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
      34
      35
      36
      diff --git a/CMakeLists.txt b/CMakeLists.txt
      index c5ed733..4c957fe 100644
      --- a/CMakeLists.txt
      +++ b/CMakeLists.txt
      @@ -4,6 +4,10 @@
      PROJECT( fc )
      CMAKE_MINIMUM_REQUIRED( VERSION 2.8.12 )

      +if(POLICY CMP0054)
      + cmake_policy(SET CMP0054 NEW)
      +endif()
      +
      MESSAGE(STATUS "Configuring project fc located in: ${CMAKE_CURRENT_SOURCE_DIR}")
      SET( CMAKE_AUTOMOC OFF )

      diff --git a/src/asio.cpp b/src/asio.cpp
      index 1313ed7..f22da17 100644
      --- a/src/asio.cpp
      +++ b/src/asio.cpp
      @@ -106,11 +106,11 @@ namespace fc {
      {
      fc::thread::current().set_name("asio");

      - BOOST_SCOPE_EXIT(void)
      - {
      - fc::thread::cleanup();
      - }
      - BOOST_SCOPE_EXIT_END
      + //BOOST_SCOPE_EXIT(void)
      + //{
      + // fc::thread::cleanup();
      + //}
      + //BOOST_SCOPE_EXIT_END

      while (!io->stopped())
      {
    • 以下cpp文件添加“/bigobj”编译属性,可能不同机器不一样,最终按编译提示来处理

      • 项目app_test
        • bitshares-core\tests\app\main.cpp
      • 项目chain_bench
        • bitshares-core\tests\common\database_fixture.cpp
      • 项目chain_test
        • bitshares-core\tests\common\database_fixture.cpp
      • 项目cli_test
        • bitshares-core\tests\cli\main.cpp
      • 项目cli_wallet
        • bitshares-core\programs\cli_wallet\main.cpp
      • 项目performance_test
        • bitshares-core\tests\common\database_fixture.cpp
      • 项目witness_node
        • bitshares-core\programs\witness_node\main.cpp

比特股环境部署-私链

发表于 2018-04-27 |

获取可执行文件

  • windows
    • 从github下载可执行文件即可
  • 其他系统
    • 从github下载源码,根据其wiki的要求进行编译

执行文件结构简介

image

  • witness_node
    • 通过 P2P 方式连接到 BTS 网络,从网络接收最新区块,向网络广播本地签署的交易包
    • 通过 websocket + http rpc 的方式提供 API 供其他程序调用
  • delayed_node
    • 通过 websocket 方式连接到 witness_node ,只包含不可回退的区块
    • 通常情况下最新区块比 witness_node 落后一分钟,异常时可能会落后很多,但可保证不可回退
    • 通过 websocket + http rpc 的方式提供 API 供其他程序调用,API清单与 witness_node 相同,但无法使用交易广播功能
  • cli_wallet
    • 通过 websocket 方式连接到 witness_node 和 delayed_node 其中之一
    • 管理钱包文件,钱包文件里包含经过加密的用户私钥,一个钱包文件可以包含多个私钥
    • 提供交易签名功能,签名后通过 witness_node 向外广播
    • 通过 http rpc 的方式提供 API 供其他程序调用
    • 推荐交易所使用一个连接到 delayed_node 的 cli_wallet 来监测用户充值,使用另一个连接到 witness_node 的 cli_wallet 来处理用户提现请求

私有链部署

witness_node 部署

  1. 生成创世块的json
    1
    ./witness_node --create-genesis-json "my-genesis.json"

工作目录下会生成一个文件:my-genesis.json

  1. 启动见证人节点
    1
    witness_node -d data --genesis-json my-genesis.json --seed-nodes "[]"
  • 工作目录下会生成一个目录:data,结构为blockchain目录、logs目录、p2p目录、config.ini配置文件。
  • 退出程序尽量不要强制关闭,按ctrl-c,等其优雅退出。数据损坏有可能需要重建索引(启动的时候使用–replay-blockchain参与)
  1. 配置config.ini,以下参数也可作为见证人节点的启动参数
    • –rpc-endpoint rpc监听端口,配置成”127.0.0.1:8090”(配置文件中不带引号)
    • –enable-stale-production 让本节点无视区块链数据的时间,无论如何都生成区块数据,配置成”true”
    • –witness-id(启动参数时可写作-w) 本节点控制的witness列表,(1.6.0-9)是默认的withness
    • –seed-nodes 要连接的peer列表(测试环境务必传此参数,不传的话会走代码里hardcode的正式网的peer列表,会导致测试节点去跟正式网络同步数据)(没有种子节点,一般用户等一年也不一定能连上网络。见证人对网络连接的要求更高,所以,必须与完整数据的种子节点相连,否则数据不完整的钱包会制造分叉)。配置成”[]”
    • –genesis-json 创世块的数据文件,配置成”my-genesis.json”
    • –track-account 参数的意思是我们只关心特别指定的账户的历史交易信息,其他账户的历史交易信息我不需要。这样就可以大大节省内存开支。
  2. 再次启动见证人节点
    1
    witness_node -d data

参数-d data 与 –data-dir data是一样的

delayed_node 部署

  1. 与 witness_node 雷同

cli_wallet 部署

  1. 启动钱包节点
    1
    ./cli_wallet --chain-id="97f304dce6fe30cccbdef37cd7899d349297a78ba483375adc3982016ef40c63" -s ws://127.0.0.1:8090 -w my-wallet.json
  • -s 或 –server-rpc-endpoint witness_node的地址和端口
  • –chain-id 指的是服务的chain-id,可以不带此参数执行一次命令,程序的报错信息会显示这个id;witness_node启动成功后也会打印出这个id
  • -w 或 –wallet-file 指的是钱包文件
  1. cli_wallet 钱包命令
  • 创建钱包

    1
    2
    3
    4
    new >>> set_password 1111
    set_password 1111
    null
    locked >>>
  • 解锁钱包

    1
    2
    3
    4
    locked >>> unlock 1111
    unlock 1111
    null
    unlocked >>>
  • 钱包导入用户

    1
    unlocked >>> import_key nathan 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3

nathan是在创世文件中定义的帐户名称,5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3是对应的私钥,在data目录下的config.ini中可以查到

  • 导入余额
    1
    unlocked >>> import_balance nathan ["5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"] true

导入的余额在创世文件中有配置,在initial_balances中,其中owner是指帐号nathan的地址。一个帐号包含三块内容,如nathan帐号{“private_key”:”5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3”,”public_key”:”BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV”,”address”:”BTSFAbAx7yuxt725qSZvfwWqkdCwp9ZnUama”},而这三个由一组brain_priv_key(16个有序的英文单词)生成。

  • 查看账户信息
    1
    unlocked >>> get_account nathan
  • 查看账户余额

    1
    unlocked >>> list_account_balances nathan
  • 升级会员

    1
    unlocked >>> upgrade_account nathan true

由于已知的缓存问题,您需要在这个阶段重新启动CLI,否则它将不知道nathan已经升级了。按Ctrl-C命令停止钱包,然后再次使用相同的命令之前启动它。

然后用get_account nathan查看,看到”membership_expiration_date”已经从”1970-01-01T00:00:00” 变成了 “1969-12-31T23:59:59”,意味着升级成功了。

  • 创建帐号
    1
    2
    3
    4
    5
    6
    7
    locked >>> suggest_brain_key
    suggest_brain_key
    {
    "brain_priv_key": "BECURSE VALGOID DEFROCK GODKIN SWITHER WORTH SUIFORM DAKER IPSEAND UPPERER PSALM UNCAST DOTTILY BEFRIZ SCUT BRONC",
    "wif_priv_key": "5KZmzKmP8869Tw26nBTtYzGM4vW55mH9R9ZTeK9wPiTeX495rbn",
    "pub_key": "BTS7KuKh66CdWb1pTRg414ocVXGDQLnrRtJDd4srevt6MRmQPd8Gg"
    }

首先生成新账户的信息。 通过使用suggest_brain_key命令来完成它

1
unlocked >>> create_account_with_brain_key "BECURSE VALGOID DEFROCK GODKIN SWITHER WORTH SUIFORM DAKER IPSEAND UPPERER PSALM UNCAST DOTTILY BEFRIZ SCUT BRONC" alpha nathan nathan true

创建帐号的创建者有两个条件,1.必须是终生会员身份(LTM);2.有足够的余额提供注册费用

  • 转账
    1
    unlocked >>> transfer nathan alpha 2000000000 BTS "here is some cash" true
  1. 其他钱包
    • 网页钱包
      • 官方钱包:https://wallet.bitshares.org
      • Transwiser支持钱包: https://bts.transwiser.com
      • DACPLAY支持钱包:https://bitshares.dacplay.org
      • 比特帝国支持钱包:https://bit.btsabc.org
      • OpenLedger支持钱包:https://bitshares.openledger.info
    • 客户端钱包
      • 官方钱包:https://bitshares.org/download/
    • 命令行钱包
      • witness_node
      • curl:curl -d ‘{“jsonrpc”: “2.0”, “method”: “info”, “params”: [], “id”: 1}’ http://localhost:8090 http://127.0.0.1:8093/rpc

添加新的witness_node

  1. 使用get_dev_key创建见证人帐号
    1
    programs/genesis_util/get_dev_key BTS w1

运行以上命令会生成一对秘钥对和地址

[{“private_key”:”5JjzogP6V1TciYQHthBLPnmj5cyrYLfwfoDeY6rpG4mcNUd7hDq”,”public_key”:”BTS6WqFcNmb8DA8SG2HJDL23TzSKk67HrCf6qTeqXhbCcohi11epm”,”address”:”BTSMZq4SyNoFGraCNuV5ZjbJHMvcYBLSV3rM”},

如果要修改创世文件的密钥对,修改以下字段initial_accounts、initial_balances、initial_witness_candidates(见证人)、initial_committee_candidates(委员会)

  1. 使用cli_wallet创建见证人帐号

使用cli_wallet创建一个帐号w2,保证其有一定余额,并将其升级成终生会员。记录公钥私钥。

1
2
3
4
locked >>> suggest_brain_key
unlocked >>> create_account_with_brain_key "BECURSE VALGOID DEFROCK GODKIN SWITHER WORTH SUIFORM DAKER IPSEAND UPPERER PSALM UNCAST DOTTILY BEFRIZ SCUT BRONC" w2 nathan nathan true
unlocked >>> transfer nathan w2 2000000000 BTS "here is some cash" true
unlocked >>> upgrade_account nathan true

详细见 cli_wallet 命令

  1. 成为见证人-配置创世文件(对应1)

修改创世文件的对应的字段,如initial_accounts、initial_balances、initial_witness_candidates(见证人)、initial_committee_candidates(委员会)

  1. 成为见证人-admin帐号使用客户端申请(对应2)
    在cli_wallet客户端中,创建witness对象,参考wiki
    1
    unlocked >>> create_witness w2 "http://url-to-proposal" true //url-to-proposal可为空

在cli_wallet客户端中,用admin帐号投票

1
unlocked >>> vote_for_witness admin w2 true true

投票成功之后,等待下次maintenance(通常是第二天0点)就可以看到我们的witness已经进入列表了,使用以下命令查询witness列表(get_global_properties)

  1. 配置和启动
    • 把公钥和私钥配置到data/config.ini文件中(private-key = [PublicKey, WIF private key])
    • 将witness-id加入config.ini(witness-id = “1.6.12”)
    • 重启witness节点,注意seed-nodes的配置

网页钱包部署

  1. Web钱包搭建
  2. 水龙头服务搭建

ethereum-theory

发表于 2018-04-19 |

区块链核心理论

  • 账本-信任+密码学=加密货币(视频地址)
  • 区块链入门教程
  • 比特币入门教程

账本(Ledger)

  1. 账本记录如:
    • A pays B ¥40
    • C pays A ¥60
    • ……
  2. 记录可伪造,所以需要加签名
    • 非对称加密:公钥(pk)和私钥(sk)
    • 用户帐号:Acc(pk)=Account
    • 签名:Sign(Message,sk)=Signature,将签名放到账本记录上
    • 签名验证:Verify(Message,Signature,pk) = T/F,公钥解密签名,得到的Message HASH值并与账本记录Message做HASH比较。
    • 签名使用AES-256
  3. 记录可复制
    • 给每条记录添加一个唯一编号
  4. 不足扣则不记录
  5. 最终账本记录如下:
      1. A pays B ¥40 (A’s Signature)
      1. C pays A ¥60 (C’s Signature)

去中心化

  1. P2P 网络
  2. 工作量证明机制(PoW,Proof of Work)
    1. 算法:SHA256(Message,RandomValue)=HashValue,改变Message的一小部份,则HashValue完全不一样,它具有散列性和不可预测性,且无法逆向。HashValue长度256位。
    2. 工作量:当RandomValue不同时,HashValue完全不一样,而区块链协议要求算出的区块的HashValue前30位为0(即尝试10E次),且随着时间,这个值会变大,则更加难易计算。
    3. P2P网络中的所有节点信任这个算法,这算法即共识算法。那么这个按此算法产生的区块整个网络都认可。
    4. 区块创建者会得到一笔奖励,起初是50,后续逐渐减半减少,减少到0为止。以BTC举例
      • 09.01 - 12.11 50BTC
      • 12.11 - 16.07 25BTC
      • 16.07 - 20.02 12.5BTC
      • 20.02 - 23.09 6.25BTC
    5. 区块产生时间:
      • BTC:10min
      • ETH:15sec
      • XRP:3.5sec
      • LTC:2.5min
  3. 账本一旦写入不能被修改。
    1. 所有区块使用默克尔树连接在一起,新的区块在后面,则导致整个区块不能修改。
  4. 当有两个或者多个节点创建出区块时,都添加到上一区块上,导致区块分叉。分叉后以区块链长的分支为准,同时取消掉其他分支。
  5. 伪造账单,会导致区块链分叉。但如果算力小于整个网络的50%,那么最终会被正确的区块链取消。

以太坊核心概念

  • 以太坊开发入门
  • V神演讲-25分钟理解以太坊
  • 对应中文翻译-上
  • 对应中文翻译-下
  • 以太坊HASH算法:KECCAK-256
  • 分叉协议:GHOST协议(GHOST protocol)=(Greedy Heaviest Observed Subtree)

智能合约

  1. 一个合约是一个帐号,它成为消息的目标,那么合约就会被调用。调用者可以是外部帐号,也可以是其他合约帐号。
  2. 合约代码运行在EVM上,并分布到整个网络每个节点
  3. 合约代码一旦发布,不可变,且永久存在
  4. 合约代码过程中状态的存储,是不可变的
  5. 智能合约开发语言:
    1. Solidity,类JS语言,其开发的合约可以用Remix IDE快速验证。官方推荐。
    2. LLL,类Lisp语言,与Solidity同一仓库
    3. Serpent,类Python语言
  6. 智能合约最佳实践

DApp

  1. 定义:相当于C/S或B/S结构中的S端,一部分放在以太坊上,由运行于以太坊网络上一个或多个智能合约的组成;另一部分可以是我们现在意义上的服务端。
  2. DApp并不把所有的状态都存储在区块链上,也不把所有的计算都放在区块链上,不然话费的Gas量太大。只把大家需要信任的东西放到区块链上。

DApp客户端

  1. 定义:相当于C/S或B/S结构中的C端或者B端。区别在于它们可能与区块链交互,也有可能与我们自己服务端交互。目前大多数的客户端用JS编写,因为可以运行在浏览器中。当然也可以用其他语言来编写。nodejs中有meteor工具来辅助开发。

DApp浏览器

  1. 用来让DApp客户端(常常使用JS与以太坊的智能合约进行交互)的使用更加容易。
  2. 主要目的:
    1. 提供到一个以太坊节点的连接(或者连接到一个本地节点或者远程节点),和一个方便的切换不同节点(甚至是不同的网络)。
    2. 提供一个帐户(或者一个钱包)来方便用户与DApp交互。
  3. 目前有哪些浏览器
    1. Mist是以太坊官方的DApp浏览器。一个漂亮的界面来与以太坊节点交互,与智能合约发、收交易。
    2. Status是一个手机上可以使用的DApp浏览器.
    3. MetaMask是一个Google浏览器扩展,把Chrome变成了一个DApp浏览器。它的核心特性是注入以太坊提供的js客户端库web3,到每一个界面,来让DApp连接到MetaMask提供的以太坊节点服务。不过这个Chrome扩展,可以允许你管理你的钱包,以及连接到不同的以太坊网络(译者注:包括本地的开发网络)。
    4. Parity是一个以太坊客户端(也是一个全节点的实现),集成到了Web浏览器,并使之成为一个DApp浏览器

GAS

  1. 定义:以太坊上每一次计算和存储所需要的费用,这个费用用gas来支付。它是用来衡量在一个具体计算中要求的费用单位。gas price就是你愿意在每个gas上花费Ether的数量,以“gwei”进行衡量。“Wei”是Ether的最小单位,1Ether=10^18Wei,1gwei=1,000,000,000 Wei。gas limit代表用户愿意花费在gas上费用的最大值。
    image
  2. 作用:
    1. 防止死循环(因为以太坊的智能合约是图灵完备的)
    2. 防止以太坊超负荷
    3. Gas限制是比特币上区块大小限制的对应物.目前的Gas上限是6.7百万gwei

账户(对应以太坊白皮书)

  1. 账户分类:
    1. 外部账户:被用户(私钥)控制的账户
    2. 合约账户:是由运行在区块链自身上的代码(合约)来控制的,即被整个区块链控制。
  2. 账户状态:
    • State consists of key value mapping addressed to account objects
    • Every account objest contains 4 pieces of data:
      • Nonce:如果账户是一个外部拥有账户,nonce代表从此账户地址发送的交易序号。如果账户是一个合约账户,nonce代表此账户创建的合约序号
      • Balance:此地址拥有Wei的数量。1Ether=10^18Wei
      • Code hash(code = empty string for private key-controlled accounts ):此账户EVM代码的hash值。对于合约账户,就是被Hash的代码并作为codeHash保存。对于外部拥有账户,codeHash域是一个空字符串的Hash值
      • Storage trie root:Merkle Patricia树的根节点Hash值。Merkle树会将此账户存储内容的Hash值进行编码,默认是空值
  3. 账户之间的关系
  • 消息由外部帐号发起,合约账户不能成为消息的发起者
    image

Coin和Token

  1. Coin,是区块链的原生货币,有自己的区块链,如BTC、LTC
  2. Token,特定的资产或者某种效力,通常以现有的一个区块链为基础。大多数的以太坊的ERC20/ERC23代币都是协议代币
  3. 两者都是Cryptocurrencies

网络,节点,区块

  1. 网络
    1. Mainnet-以太坊主网,通常是所有客户端的默认网络。
    2. Ropsten - 以太坊使用工作量证明的主测试网络。这个网络,因为低的计算量,容易遭到DDOS攻击,分片,或者其它问题。垃圾邮件攻击后被暂时放弃,最近才恢复使用。
    3. Kovan-parity客户端组成的测试网络,使用授权证明来提升对垃圾邮件攻击的抗扰度,并且持续4秒的阻塞时间。
    4. Rinkeby-geth客户端组成的测试网络,使用集团共识,尽管计算量低,但是对恶意行为者更有弹性。
  2. 节点
    1. 定义:为区块链网络中的一台电脑(简单理解的话,再详细点是指那个区块链进程)存放了整个区块链的数据。节点分成全节点(有完整的数据)和轻节点。可以通过geth来运行一个全节点(官方的节点,go语言),或者parity来运行一个轻节点。
  3. 区块
    1. 区块包含:
      1. 区块头
        • parentHash:父区块头的Hash值(这也是使得区块变成区块链的原因)
        • ommerHash:当前区块ommers列表的Hash值
        • beneficiary:接收挖此区块费用的账户地址
        • stateRoot:状态树根节点的Hash值
        • transactionsRoot:包含此区块所有交易的Merkle树的根节点Hash值
        • receiptsRoot:包含此区块所有交易收据的Merkle树的根节点Hash值
        • logsBloom:由日志信息组成的一个Bloom过滤器 (一种数据结构)
        • difficulty: 此区块的难度级别
        • number:当前区块的计数(创世纪块的区块序号为0,对于每个后续区块,区块序号都增加1)
        • gasLimit:每个区块的当前gas limit
        • gasUsed: 此区块中交易所用的总gas量
        • timestamp:此区块成立时的unix的时间戳
        • extraData:与此区块相关的附加数据
        • mixHash:一个Hash值,当与nonce组合时,证明此区块已经执行了足够的计算
        • nonce:一个Hash值,当与mixHash组合时,证明此区块已经执行了足够的计算
          image
      2. 关于包含在此区块中的交易集信息
      3. 与当前区块的ommers相关的一些列其他区块头

开发工具和开发库

  1. 发布框架
    1. Truffle框架 & Truffle教程
    2. Embark框架
  2. 去中心化的智能合约包管理资源库
    1. ETHP & 使用教程
  3. 反编译智能合约/Disassembly
    1. 可以通过prosity来反编译以太坊智能合约的字节码,可以使用evmdis来Disassembly。
  4. Whisper是一个集成进以太坊的消息系统。它允许DApp发布小量的信息来进行非实时的消息通信。使用ssh协议。一个使用Whisper协议实现一个聊天客户端的例子
  5. Open Zeppelin是一系列经过审查的,最佳的智能合约实践,你可以继承并应用于你自己的DApp中。github学习资源

应用项目

  1. 去中心自动化组织
  2. Aragon设计一个根据智能合约逻辑运作的公司,重点是创建一个可以接受投资,处理会计,支付雇员,分配股权,正如我们现在知道的完成每天的公司的业务。他们也实现了漂亮的DApp客户端来让他们的协议使用起来更为简单。
  3. IPFS(星际文件系统)是一个协议,用来分发文件。
  4. FileCoin是Protocol Lab为创建一个去中心化的基于IPFS的存储市场的努力结果,也就是向整个网络提供存储资源的激励层
  5. Swarm是一个去中心化的存储网络,集成于以太坊生态系统
  6. Augur是一个去中心化的预测市场,让大家对于某个现实世界的事件进行对赌
  7. Gnosis与Augur有类似的理念,也是一个去中心化的预测市场
  8. Golem是一个分布式的算力市场
  9. 0xProject创建了一个交换代币的协议,以及一个DApp来实现这个协议。
    10.district0x是一个更高层级的去中心化的市场和社区。
  10. uPort在解决去中心化的身份识别问题。

一些公司

  1. ConsenSys(有点像共识Consensus,但作为一个公司名称;它很聪明,巧妙的把u改成了s,但我一般念为“con-SEn-SIS”,避免读错)是一个“风险投资和产品工作室”。他们是一个(其实非常大)伞形组织,它赞助了一大堆项目和核心组件的开发。值得一提的是,它们资助了Truffle,Infura,MetaMask,Gnosis和uPort。
  2. Zeppelin Solutions在上面我们有提到过,他也审查智能合约代码,提供咨询服务。他们的博客质量相当高。
  3. Protocol Labs是一群让人印象深刻的人,致力于IPFS,FileCoin,lip2p以及IPLD等其它项目的开发。

以太坊白皮书学习记录

发表于 2018-04-17 |

以太币白皮书中文文档

比特币的核心概念

作为状态转换系统的比特币

  1. 转换函数

    1
    APPLY(S,TX) ­> S' or ERROR
    • 转换函数解析:
      1. 交易的每个输入:
        • 如果引用的UTXO不存在于现在的状态中(S),返回错误提示
        • 如果签名与UTXO所有者的签名不一致,返回错误提示
      2. 如果所有的UTXO输入面值总额小于所有的UTXO输出面值总额,返回错误提示
      3. 返回新状态S’,新状态S’中移除了所有的输入UTXO,增加了所有的输出UTXO
  2. 状态结构(UTXO:未花费的交易输出,unspent transaction outputs),包含一个面值和所有者(由20个字节的本质上是密码学公钥的地址所定义[1])。一笔交易包括一个或多个输入和一个或多个输出。每个输入包含一个对现有UTXO的引用和由与所有者地址相对应的私钥创建的密码学签名。每个输出包含一个新的加入到状态中的UTXO。

挖矿

  1. 区块
    1. 网络中的节点不断尝试把交易结果打包成“区块”
    2. 区块大约每十分钟产生一块
    3. 每个区块包含:时间戳、随机数、对上一个区块的引用(即hash值)、上一区块生成以来发生的所有交易列表。核对规则如下:
      • 检查区块引用的上一个区块是否存在且有效
      • 检查区块的时间戳是否晚于以前的区块的时间戳,而且早于未来2小时
      • 检查区块的工作量证明是否有效
      • 将上一个区块的最终状态赋于S[0]
      • 假设TX是区块的交易列表,包含n笔交易。对于属于0……n-1的所有i,进行状态转换S[i+1] = APPLY(S[i],TX[i])。如果任何一笔交易i在状态转换中出错,退出程序,返回错误。
      • 返回正确,状态S[n]是这一区块的最终状态
  2. 矿工的作用和奖励
    1. 使用共识算法“工作量证明”,即不停的创建区块,并设置区块的随机值等随机手段,然后hash这个区块,得出hash值是否小于2^190(190是随着比特币的增长,不断变小的值),即为创建区块成功。创建区块者可以得到25BTC的奖励
    2. 矿工将交易打包到区块链。交易中的输入往往大于输出,差额部分就作为“交易费用”付给矿工。

默克尔树

  1. 定义:默克尔树是一种二叉树,由一组叶节点、一组中间节点和一个根节点构成。最下面的大量的叶节点包含基础数据,每个中间节点是它的两个子节点的哈希,根节点也是由它的两个子节点的哈希,代表了默克尔树的顶部。
  2. 特点:允许区块的数据可以零散地传送。节点可以从一个源下载区块头,从另外的源下载与其有关的树的其它部分,而依然能够确认所有的数据都是正确的

比特币智能合约的问题

  1. 缺少图灵完备
  2. 价值盲
  3. 缺少状态
  4. 区块链盲

以太坊的核心概念

以太坊账户

  1. 以太坊状态:是由被称为“账户”的对象和在两个帐号之间转移价值和信息的状态转换构成
  2. 以太坊账户包含四个部分:
    1. 随机数,用于确定每笔交易只能被处理一次的计数器
    2. 账户目前的以太币余额
    3. 账户的合约代码,如果有的话
    4. 账户的存储,默认为空
  3. 分成两类账户:外部所有账户(私钥控制)、合约账户(合约代码控制)

消息和交易

  1. 消息,类似于比特币的交易,但有三点不同
    1. 以太坊的消息可以由外部实体或者合约创建,然而比特币的交易只能从外部创建
    2. 以太坊消息可以选择包含数据
    3. 如果以太坊消息的接受者是合约账户,可以选择进行回应,这意味着以太坊消息也包含函数概念
  2. 交易是指存储的从外部账户发出的消息的签名数据包,包含
    1. to:消息的接收者
    2. v,r,s:用于确认发送者的签名
    3. value:从发送者转移到接收者Wei的数量。在合约创建交易中,value作为新建合约账户的开始余额
    4. data(可选域,只有在消息通信中存在):消息通信中的输入数据(也就是参数)。例如,如果智能合约就是一个域名注册服务,那么调用合约可能就会期待输入参数:域名和IP地址
    5. STARTGAS值:发送者愿意为执行交易支付gas数量的最大值。此值设置之后在任何计算完成之前就会被提前扣掉
    6. GASPRICE值:发送者愿意支付执行交易所需的每个gas的Wei数量
    7. nonce:发送者发送交易数的计数
    8. init(只有在合约创建交易中存在):用来初始化新合约账户的EVM代码片段。init值会执行一次,然后就会被丢弃。当init第一次执行的时候,它返回一个账户代码体,也就是永久与合约账户关联的一段代码。
  3. 创建合约有单独的交易类型和相应的消息类型;合约的地址是基于账号随机数和交易数据的哈希计算出来的

以太坊状态转换函数

  1. 状态转换函数

    1
    APPLY(S,TX) ­> S' or ERROR
    • 转换函数解析:
      1. 检查交易的格式是否正确(即有正确数值)、签名是否有效和随机数是否与发送者账户的随机数匹配。如否,返回错误
      2. 计算交易费用:fee=STARTGAS * GASPRICE,并从签名中确定发送者的地址。从发送者的账户中减去交易费用和增加发送者的随机数。如果账户余额不足,返回错误
      3. 设定初值GAS = STARTGAS,并根据交易中的字节数减去一定量的瓦斯值
      4. 从发送者的账户转移价值到接收者账户。如果接收账户还不存在,创建此账户。如果接收账户是一个合约,运行合约的代码,直到代码运行结束或者瓦斯用完。
      5. 如果因为发送者账户没有足够的钱或者代码执行耗尽瓦斯导致价值转移失败,恢复原来的状态,但是还需要支付交易费用,交易费用加至矿工账户。
      6. 否则,将所有剩余的瓦斯归还给发送者,消耗掉的瓦斯作为交易费用发送给矿工

代码执行

  1. 以太坊虚拟机:EVM
  2. 可以访问三种数据空间:堆栈、内存、合约的长期存储

区块链和挖矿

  1. 每个区块:不仅包含交易记录和最近的状态,还包含区块序号和难度值。核对规则如下
    1. 检查区块引用的上一个区块是否存在和有效
    2. 检查区块的时间戳是否比引用的上一个区块大,而且小于15分钟
    3. 检查区块序号、难度值、 交易根,叔根和瓦斯限额(许多以太坊特有的底层概念)是否有效
    4. 检查区块的工作量证明是否有效
    5. 将S[0]赋值为上一个区块的STATE_ROOT
    6. 将TX赋值为区块的交易列表,一共有n笔交易。对于属于0……n-1的i,进行状态转换S[i+1] = APPLY(S[i],TX[i])。如果任何一个转换发生错误,或者程序执行到此处所花费的瓦斯(gas)超过了GASLIMIT,返回错误。
    7. 用S[n]给S_FINAL赋值, 向矿工支付区块奖励
    8. 检查S_FINAL是否与STATE_ROOT相同。如果相同,区块是有效的。否则,区块是无效的
  2. 矿工的奖励,同比特币

应用

  1. 代币系统
  2. 金融衍生品和价值稳定的货币
  3. 身份和信誉系统
  4. 去中心化存储
  5. 去中心化资质组织
  6. 其他
    1. 储蓄钱包
    2. 作物保险
    3. 一个去中心化的数据发布器
    4. 云计算
    5. 点对点赌博
    6. 预测市场
    7. 链上去中心化市场
1234

Lucus Gu

32 日志
2 标签
RSS
© 2017 — 2019 Lucus Gu
由 Hexo 强力驱动
|
主题 — NexT.Mist v5.1.4