Ethereum Blockchain Block Raw Data in brief

Ethereum Blockchain Block Raw Data in brief

缘起

由于最近在看智能合约相关内容,但一个对区块链有一些隐约的困惑,没有一个感性的认识。于是有了想分析区块内容的想法,以便能更深刻的认识区块链。其次最近简单学习了以太坊区块数据的格式,做个简答小结。主要资料可参考 Ethereum Wiki

区块格式

以太坊区块格式

主要参考这里
一个完整的区块定义格式是这样的

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
[
block_header,
transaction_list,
uncle_list,
stack_trace
]
其中:
transaction_list = [
transaction 0,
transaction 1,
...
]
uncle list = [
uncle_block_header_1,
uncle_block_header_2,
...
]
block_header = [
parent hash,
number,
TRIEHASH(transaction_list),
TRIEHASH(uncle_list),
TRIEHASH(stack_trace),
coinbase address,
state_root,
difficulty,
timestamp,
extra_data,
nonce
]
stack_trace = [
[ medhash 0, stkhash 0 ],
[ medhash 1, stkhash 1 ],
...
]

比如一个私链上的创世块是这样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
rawData:
f901f8f901f3a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0a4328ecabdd749f4e24d190cd2bd00f6609f3334bf94a55fc2ea3e4ede05a44ba056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008240008084ffffffff808080a00000000000000000000000000000000000000000000000000000000000000000880000000000000042c0c0
解析各个部分并按rfc定义用RLP编码转16进制输出
BlockData [
truehash=55da6a62b7a8d0a438aa3934d3571b12269eb7c011a4e62df171de5c05fd2853
true hash=55da6a62b7a8d0a438aa3934d3571b12269eb7c011a4e62df171de5c05fd2853
true parentHash=0000000000000000000000000000000000000000000000000000000000000000
true unclesHash=1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
true coinbase=0000000000000000000000000000000000000000
true stateRoot=a4328ecabdd749f4e24d190cd2bd00f6609f3334bf94a55fc2ea3e4ede05a44b
true txTrieHash=56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
true receiptsTrieHash=56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
true difficulty=4000
true number=0 gasLimit=ffffffff
true gasUsed=0 timestamp=0 (1970.01.01 08:00:00)
true extraData=
true mixHash=0000000000000000000000000000000000000000000000000000000000000000
true nonce=0000000000000042
trueUncles []
trueTxs []
]

每个transaction 和uncle_block_header 都是一张表。工作量证明数据是区块数据去除掉nonce(交易数)后的RLP编码。
uncle_list 和 transaction_list 分别是叔区块头和区块里的交易构成的表。nonce 和 extra_data 都被限制为最大32字节,除了在创世区块中参数extra_data会更大。
state_root 是一个包含所有地址的(key, value)对的默克尔-帕特里夏树(Merkle Patricia tree )的根, 其中每一个地址都由一个20字节二进制字符串表示。对于每个地址,储存在默克尔-帕特里夏树的 value 字段是一个对以下格式对象进行RLP串接编码形成的字符串:
[ balance, nonce, contract_root, storage_deposit ]

nonce 是该地址的交易数,每做一次交易都会增加1。其目的是(1)使每个交易只有一次合法的机会以防范重放攻击,(2)使得构建一个和已存合约有相同哈希的合约成为不可能(更准确地说,密码学意义上不可行)。balance 指的是合约或地址的平衡账目,以伟为单位。contract_root 是另一个帕特里夏树的根,在该地址被一个合约控制的情况下包含该合约的内存。如果一个地址没有被一个合约控制,contract_root 就会是一个空字符串。storage_deposit是一个计数器,储存花费的储存费用

注 RLP 递归长度前缀编码 (recursive length prefix encoding,RLP)
这种编码格式将任意长度和维度的字符串构成的数组串接成字符串。例如,[‘dog’, ‘cat’]被串接 (以字节数组格式) 为 [ 130, 67, 100, 111, 103, 67, 99, 97, 116];其基本的思想是把数据类型和长度编码成一个单独的字节放在实际数据的前面(例如‘dog’的字节数组编码为[ 100, 111, 103 ], 于是串接后就成了[ 67, 100, 111, 103 ].)注意RLP编码正如其名字表示的一样,是递归的;当RLP编码一个数组时,实际上是在对每一个元素的RLP编码级联成的字符串编码。需要进一步提请注意的是,以太坊中所有数据都是整数;所以,如果有任何的以一个或多个0字节开头的哈希或者地址,这些0字节应该在计算出现问题的时候去除。以太坊中没有串接数据结构包含任何以0开头的数值。整数以大端基础256格式存储(例如32767字节数组格式为[ 127, 255 ])。

详细代码可以参考ethereumj中Block的代码部分
blockchain

bitcoin 区块格式

关于bitcoin的区块格式,已经有前人做了分析大致结构如下
blockchain-fmt
blockchain-fmt
blockchain-fmt
比特币创世区块是这样的
blockchain-fmt

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
{
"txid" : "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
"version" : 1,
"locktime" : 0,
"vin" : [
{
"coinbase" : "04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73",
"sequence" : 4294967295
}
],
"vout" : [
{
"value" : 50.00000000,
"n" : 0,
"scriptPubKey" : {
"asm" : "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f OP_CHECKSIG",
"hex" : "4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac",
"reqSigs" : 1,
"type" : "pubkey",
"addresses" : [
"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
]
}
}
]
}

blockchain-fmt
blockchain-fmt
blockchain-fmt
blockchain-fmt
blockchain-fmt

关键代码在 bitcoinj 的Block的代码
blockchain

基于以太坊的智能合约开发入门

基于以太坊的智能合约开发入门

环境安装

现在我选择这里 Ubuntu 16.10 LTS 版本

  • 安装nodejs 环境 (通过apt-get 安装的默认是nodejs 4.2.6) 建议安装官网较新的版本
  • 接着修改registry地址 为淘宝镜像或者其他国内镜像可以加速包安装过程

    1
    2
    npm config set registry https://registry.npm.taobao.org
    npm info underscore (如果上面配置正确这个命令会有字符串response)
  • 可选安装yarn 一个号称能比npm更快的包管理工具 ( npm install -g yarn )

  • 如果不是安装的最新的nodejs 可以用下面的方法升级( npm install -g n && n stable )
  • 接下来安装 truffle ( npm install -g truffle 或者使用yarn 安装 yarn global add truffle )
  • 安装 testrpc 或者 geth ( 开发测试可以直接安装 testrpc npm install -g testrpc ; yarn global add testrpc )
  • 安装 solc 用web3js 可以生成 abi文件和bin文件 ( npm install -g solc ; yarn global add solc )
  • 下载安装web3j wapper tool web3j tool
    解压即可使用 bin/web3j solidity generate … …

    npm 和yarn命令转换cheat sheet
    image

使用truffle 初始化项目,并编写智能合约,生成智能合约abi文件和bin文件等

  • 初始化项目 truffle-demo ( mkdir truffle-demo && cd truffle && truffle init )

    image
    image

  • 编写智能合约,并编译 ( truffle compile )
    image
    image
  • 启动区块链测试环境 testrpc
    image
  • 修改配置文件 truffle.js 的host为127.0.0.1或者localhost ,端口按testrpc提示修改

  • 修改migration目录下的migrate 文件 执行 ( truffle migrate )
    image
    image
    image

  • truffle console 进入控制台进行简单验证
    image
    image
    image
  • truffle build 编译

  • truffle publish 发布

  • truffle networks 发布
    image

  • 导出abi文件和bin文件 ( solcjs contracts/ConvertLib.sol –abi –bin –optimize -o build/ –verbose )
    image
    image
  • 导出abi文件和bin文件 ( web3j solidity generate xxx.bin xxx.abi -p com.xxx.smart.contracs -o outputdir )
    注意参数有先后顺序,先xxx.bin 再xxx.abi 反了会报错的
    image
    image
    image
    image

TODO TBD

mongodb 3.4.x 入门笔记

安装

现在我选择这里 https://www.mongodb.com/download-center/enterprise/releases

linux 更简单快捷的方式 centos 或者 redhat

参考这里

创建repo文件 /etc/yum.repos.d/mongodb-enterprise.repo 直接用yum安装mongodb

1
2
3
4
5
6
[mongodb-enterprise]
name=MongoDB Enterprise Repository
baseurl=https://repo.mongodb.com/yum/redhat/$releasever/mongodb-enterprise/3.4/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc

最后执行 yum install -y mongodb-enterprise

简单配置

mongodb 默认的配置文件在 /etc/mongod.conf

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
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /home/mongodb/mongo/log/mongod.log
# Where and how to store data.
dbpath=/home/mongodb/mongo/data/db
storage:
dbPath: /home/mongodb/mongo/data
journal:
enabled: true
# engine:
# mmapv1:
# wiredTiger:
# how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /var/run/mongodb/mongod.pid # location of pidfile
# network interfaces
net:
port: 27017
#bindIp: 127.0.0.1 # Listen to local interface only, comment to listen on all interfaces.
enabled: true
JSONPEnabled: true
RESTInterfaceEnabled: true
#security:
#operationProfiling:
#replication:
#sharding:
## Enterprise-Only Options
#auditLog:
#snmp:

比如要启动一个单节点的mongod实例
可以这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dbpath=/home/mongodb/mongo/data/db/
logpath=/home/mongodb/mongo/data/log
maxConns=100
logRotate=rename
pidfilepath=/home/mongodb/mongo/data/mongo.pid
httpinterface=on
auth=true
rest=true
jsonp=true
noprealloc=true
smallfiles=true
directoryperdb=true
nounixsocket=true
port=27017
fork=true

然后 mongod -f mongod.conf
这事启动是带有认证的

需要正常使用则应该先了解 内置role介绍
mongo 127.0.0.1:27017/admin
db.createUser({user:’adminxxx’,pwd:’passwordxxx’,roles:[‘root’]});
db.auth(‘username’,’password’);
然后创建普通用户
需要

db.createUser({user:’zjexxxx’,pwd:’passwordxxx’,roles:[{role:’dbOwner’,db:’yourdbname’]});
db.auth(‘username’,’password’);
use yourdbname;
就可以操作数据库了

使用其他客户端 比如 mongoimport 导入csv我文件

1
2
3
4
mongoimport --authenticationDatabase admin -u 'username' -p 'password' -d
SH_stock -c 600000 --type=csv --fields='a1.string','a2.string','a3.double',
'a4.double','a5.double','a6.double','a7.int64',
'a8.double' --file=./SH#600000.csv

关于用户创建的一点提示

  • 首先 mongo 连接上去

    use admin
    db.auth(‘admin’,’password’); //管理员认证
    use db_zjex;
    db.createUser({user:’zjexxxx’,pwd:’passwordxxx’,roles:[{role:’dbOwner’,db:’db_zjex’]});
    这种方式创建的用户 连接时可以直接
    mongo ip:27017/db_zjex -u zjexxxx -p passwordxxx
    或者

    1
    mongo ip:27017/db_zjex -u zjexxxx -p passwordxxx --authenticationDatabase db_zjex
  • 如果是下面的方式创建用户
    首先 mongo 连接上去

    use admin
    db.auth(‘admin’,’password’); //管理员认证
    db.createUser({user:’zjexxxx’,pwd:’passwordxxx’,roles:[{role:’dbOwner’,db:’db_zjex’]});
    这种方式创建的用户 连接时可以直接

    1
    mongo ip:27017/db_zjex -u zjexxxx -p passwordxxx --authenticationDatabase admin

spaceemacs 学习笔记

  1. gg moves to the beginning of the buffer.
    G moves to the end of the buffer.
    : followed by a line number the moves to that line number .

    1. typing / followed by a pharse searches FORWARD for the pharse.
      typing ? followed by a pharse searches BACKWORD for the pharse.
      After a search type n to find the next occurrence in the same direction
      or N to search in the opposite direction.

    2. typing % while the cursor is on a(,),[,],{,or} locates its matching pair.

    3. To substitute new for the first old on a line type :s/old/new
      To substitute new for all ‘old’s on a line type :s/old/new/g
      To substitute phrases between two line #’s type :#,#s/old/new/g
      To substitute all occurrences in the file type :%s/old/new/g
      To ask for confirmation each time add ‘c’ :%s/old/new/gc

    4. To save part of a file type :#,# w filename

Why is char[] preferred over String for passwords in Java?

Why is char[] preferred over String for passwords in Java?

来自 stackoverflow 的一个热门讨论
In Swing, the password field has a getPassword() (returns char[]) method instead of the usual getText() (returns String) method. Similarly, I have come across a suggestion not to use String to handle passwords.

Why does String pose a threat to security when it comes to passwords? It feels inconvenient to use char[]

ans1

  • Strings are immutable. That means once you’ve created the string, if another process can dump memory, there’s no way (aside from reflection) you can get rid of the data before garbage collection kicks in.

With an array, you can explicitly wipe the data after you’re done with it. You can overwrite the array with anything you like, and the password won’t be present anywhere in the system, even before garbage collection.

So yes, this is a security concern - but even using char[] only reduces the window of opportunity for an attacker, and it’s only for this specific type of attack.

As noted in comments, it’s possible that arrays being moved by the garbage collector will leave stray copies of the data in memory. I believe this is implementation-specific - the garbage collector may clear all memory as it goes, to avoid this sort of thing. Even if it does, there’s still the time during which the char[] contains the actual characters as an attack window.

ans2

While other suggestions here seem valid, there is one other good reason. With plain String you have much higher chances of accidentally printing the password to logs, monitors or some other insecure place. char[] is less vulnerable.

Consider this:

public static void main(String[] args) {
Object pw = “Password”;
System.out.println(“String: “ + pw);

pw = “Password”.toCharArray();
System.out.println(“Array: “ + pw);
}
Prints:

String: Password
Array: [C@5829428e

ans3

To quote an official document, the Java Cryptography Architecture guide says this about char[] vs. String passwords (about password-based encryption, but this is more generally about passwords of course):

It would seem logical to collect and store the password in an object of type java.lang.String. However, here’s the caveat: Objects of type String are immutable, i.e., there are no methods defined that allow you to change (overwrite) or zero out the contents of a String after usage. This feature makes String objects unsuitable for storing security sensitive information such as user passwords. You should always collect and store security sensitive information in a char array instead.
Guideline 2-2 of the Secure Coding Guidelines for the Java Programming Language, Version 4.0 also says something similar (although it is originally in the context of logging):

Guideline 2-2: Do not log highly sensitive information

Some information, such as Social Security numbers (SSNs) and passwords, is highly sensitive. This information should not be kept for longer than necessary nor where it may be seen, even by administrators. For instance, it should not be sent to log files and its presence should not be detectable through searches. Some transient data may be kept in mutable data structures, such as char arrays, and cleared immediately after use. Clearing data structures has reduced effectiveness on typical Java runtime systems as objects are moved in memory transparently to the programmer.

This guideline also has implications for implementation and use of lower-level libraries that do not have semantic knowledge of the data they are dealing with. As an example, a low-level string parsing library may log the text it works on. An application may parse an SSN with the library. This creates a situation where the SSNs are available to administrators with access to the log files.

ans4

Character arrays (char[]) can be cleared after use by setting each character to zero and Strings not. If someone can somehow see the memory image, they can see a password in plain text if Strings are used, but if char[] is used, after purging data with 0’s, the password is secure.

Chromium 命令行启动参数

Chromium命令行启动参数

说明
常用命令行启动参数列表
如何使用这些参数
说明

这个页面列出了一些常用的命令行启动参数以及对它们的简要说明。说明中括号里的内容为译者注。

对于选项页 ( chrome://settings/ ) 或实验页 ( chrome://flags/ ) 已明确给出可视选项的参数,本列表不再包含。

更新更全的列表可以参考这里(英文,约500条,每日更新) http://peter.sh/experiments/chromium-command-line-switches/

这些参数的使用方法见本文末尾。

常用命令行启动参数列表

序号 参数 说明
1 –allow-outdated-plugins 不停用过期的插件。
2 –allow-running-insecure-content 默认情况下,https 页面不允许从 http 链接引用 javascript/css/plug-ins。添加这一参数会放行这些内容。
3 –allow-scripting-gallery 允许拓展脚本在官方应用中心生效。默认情况下,出于安全因素考虑这些脚本都会被阻止。
4 –disable-accelerated-2d-canvas 停用 GPU 加速二维画布。
5 –disable-accelerated-video 停用 GPU 加速视频。
6 –disable-dart 停用 Dart。
7 –disable-desktop-notifications 禁用桌面通知,在 Windows 中桌面通知默认是启用的。
8 –disable-extensions 禁用拓展。
9 –disable-file-system 停用 FileSystem API。(注意一些拓展如 Adblock Plus for Google Chrome™ 依赖此 API 运行)
10 –disable-java 停用 Java。
11 –disable-local-storage 禁用 LocalStorage。
12 –disable-preconnect 停用 TCP/IP 预连接。
13 –disable-remote-fonts 关闭远程字体支持。SVG 中字体不受此参数影响。
14 –disable-speech-input 停用语音输入。
15 –disable-sync 停用同步功能。
16 –disable-ssl3 停用 SSL v3。
17 –disable-web-security 不强制遵守同源策略,供网站开发人员测试站点使用。
18 –disk-cache-dir 将缓存设置在给定的路径。
19 –disk-cache-size 设置缓存大小上限,以字节为单位。
20 –dns-prefetch-disable 停用DNS预读。
21 –enable-print-preview 启用打印预览。
22 –extensions-update-frequency 设定拓展自动更新频率,以秒为单位。
23 –incognito 让浏览器直接以隐身模式启动。
24 –keep-alive-for-test 最后一个标签关闭后仍保持浏览器进程。(某种意义上可以提高热启动速度,不过你最好得有充足的内存)
25 –kiosk 启用kiosk模式。(一种类似于全屏的浏览模式)
26 –lang 使用指定的语言。
27 –no-displaying-insecure-content 默认情况下,https 页面允许从 http 链接引用图片/字体/框架。添加这一参数会阻止这些内容。
28 –no-first-run 跳过 Chromium 首次运行检查。
29 –no-referrers 不发送 Http-Referer 头。
30 –no-sandbox 彻底停用沙箱。
31 –no-startup-window 启动时不建立窗口。
32 –proxy-pac-url 使用给定 URL 的 pac 代理脚本。(也可以使用本地文件,如 –proxy-pac-url=”file:\\c:\proxy.pac”)
33 –proxy-server 使用给定的代理服务器,这个参数只对 http 和 https 有效。(例如 –proxy-server=127.0.0.1:8087 )
34 –show-component-extension-options 让自带的拓展组件显示在 chrome://settings/extensions 里。(目前有一个 “Bookmark Manager 0.1″)
35 –single-process 以单进程模式运行 Chromium。(启动时浏览器会给出不安全警告)
36 –skip-gpu-data-loading 跳过启动时的 GPU 信息收集、黑名单读取与黑名单自动更新,这样一来,所有的 GPU 功能都可供使用,并且 about:gpu 页面会显示空白。此参数仅供测试使用。
37 –start-maximized 启动时最大化。
38 –touch-optimized-ui 使用对触屏更友好的用户界面。(目前来看似乎只是把一些字体放大了)
39 –user-agent 使用给定的 User-Agent 字符串。
如何使用这些参数

可以参考 Chromium 团队的这个说明(英文) http://www.chromium.org/developers/how-tos/run-chromium-with-flags

对于 Windows 系统,简单来说就是:

在快捷方式上右键,选择属性。
选择“快捷方式”标签。
在“目标”一行的末尾,添加上启动参数。
最终效果应该像这样: ……\chrome.exe –first-switch –second-switch

加上命令行选项:–kiosk即可。

发现另外一个option也可以:–app=。这个option也是启动全屏,而且会自动打开指定的URL。

经过不懈的查找,终于在stackoverflow上找到一个人的帖子,描述了他用一种奇怪的方法来解决这个问题,也就是chrome的kiosk模式和kiosk printing模式。当浏览器启动的时候,在后面加上–kiosk –kiosk-printing的参数,就能进入该模式,在该模式下,除了页面内容之外,其他的诸如地址栏,工具栏按钮神马的,都不见了,并且只能通过ALT F4来关闭。我猜想这个模式是给展示用的,比如某些特殊的场合。这个模式有一个好处,就是打印的时候不需要二次确认,这个也好理解,比如你做了一个自动售票的页面,出票机就是你的打印机,你在页面上点击一下出票,立刻票就从打印机里出来了,不需要出打印机的设置框。

通过这种方式打开页面,就能全屏并且打印不需要确认了。

目前比较流行的Python科学计算发行版

Anaconda

[Anaconda ](https://www.continuum.io/downloads)
这个是新起之秀,就今年已更新多次了,目前的版本是2.3.0。包管理使用conda,GUI基于PySide,
所有的包基本上都是最新版,没有PyQt和wxpython等,容量适中,但该有的科学计算包都有:
numpy,sicpy,matplotlib,spyder.....,目前我的CenTOS系统服务器安装的就是这个。
Linux系统里面,Anaconda安装、更新和删除都很方便,且所有的东西都只安装在一个目录中
/home/wxp/anaconda/,这点比下面的Canopy要好得多.Anaconda的开发和维护中有Python创始
人和社区的核心成员,可以想象这个发行包肯定会"后来居上"!Anaconda目前提供Python 2.6.9,
Python 2.7.X和Python 3.4.X三个系列发行包,这也是其他发行版所望尘莫及的。因此在各种操作
系统中,无论是Linux,还是Windows,又或是Mac,我都强烈推荐Anaconda!

Enthought Canopy (Enthought Python Distribution)

[Enthought Python Distribution](https://store.enthought.com/downloads/)
Enthought目前的版本是1.7.4. GUI基于wxpython,包含PySide,但不包括PyQt. WxPython使用起来是
比较方便,但是远没有PyQt和PySide流行,需要使用PyQt的可以自己安装。Canopy有自己的集成开发
环境(IDE),里面的代码智能提示和自动补全功能不比IPython差的!Canopy中还集成了Pyhton包的
在线升级和管理系统,很是方便。由于是商业级别的,Canopy的性能和稳定性超强!也提供免费的free
版本和学术版本(用于教育科研也是免费的)。以前叫EPD,现在改名叫Canopy。Canopy是第一个将
Ipython升级到2.3.0的发行版;MatPlotLib已升级到1.4.2;NumPy 1.8.1;Scipy 1.2.0. 
但是它主要是追求性能和稳定性,所以不能指望所有的安装包都是最新的,例如对于MinGW,
Canopy是4.8.1,其它版本的发行版可都是4.7呀!basemap官方的业已换成1.0.8了,这对于那些还在被
迫使用Grads和NCL的用户而言是个福音!如果你有学校邮箱的话,可以在Enthought的网站注册一下,
选择学术+full的发行版本,会让你的工作如虎添翼的。 

Sage

[目前Sage 最新版本是7.3](http://www.sagemath.org/index.html)
万众瞩目的发行版,其目标是要干掉:MATLAB, MAPLE, MATCAD, Mathematica等。目前我也在学习中。
由于大名鼎鼎的MatPlotLib(stable 1.4.2),IPython(stable 2.3.0),Numpy(stable 1.9.1)
和Scipy(0.14.1)都已发布最新稳定版,要不了几个月,上面的发行版都会迎来较大的一次更新,
让我们拭目以待吧!

Python(x,y)

GUI基于PyQt,曾经是功能最全也是最强大的,而且是Windows系统中科学免费Python发行版的不二选择.
不过今时已不同往昔! PythonXY里面的许多包为了兼容性的问题,无法使用最新的程序包。尤其是令人
气愤的是MinGW到现在还是古董级的4.5版本,而TDM-GCC现在都4.8.1-3了。不过这个包在你安装了之后,
除了占用较大的磁盘空间之外,基本上你也不用再费什么神去找了,对于科学计算要有的基本都有了:
numpy,sicpy,matplotlib,spyder... 现在的版本是2.7.9。从安装到使用,时不时玩"崩溃"! 
版本的稳定性远不如2.7.3.1.我估计可能是作者把主要精力转移到开发和维护WinPython上面去的原因吧!

WinPython

WinPython功能也是比较全的,软件包比较新,GUI基于PyQt,不过相对于Python(x,y),它主要是关注
便携式安装体验:你可以把它装在u盘里面。我现在windows中已不再使用PythonXY了,改成WinPython了,
对于MinGW,我直接安装了QT5.20(含MinGW4.8.0),再加上boost 1.54.0,用于科研,已非Visual 
Studio可以相提并论!现在的版本是2.7.10.稳定性已有相当的改善.
发布的版本也比较全:                               

mysql root密码重置

新装的mysql 或者用过一段时间的测试机mysql数据库忘了密码,又不想重装。想来应该有办法可以重置密码。
首先想到mysqladmin 但是尝试在后无果,还是需要密码。经过一番查找尝试还是有高人,废话不多说了,光说不练假把式。看我如何操作

1
2
3
4
5
6
7
8
/etc/init.d/mysql stop
mysqld_safe --user=mysql --skip-grant-tables --skip-networking &
mysql -u root mysql
update user set password=password('mysqlroot@') where user='root';
FLUSH PRIVILEGES;
/etc/init.d/mysql restart
mysql -uroot -p
输入先设置的密码 ok

python 操作mysql

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/bin/python
#coding=utf-8
import MySQLdb
import time
from collections import OrderedDict
from colorama import init, Fore
class Mysql(object):
'''
获取当前系统时间
2016-08-30 11:13:18
'''
def get_current_time(self):
created_time = time.strftime(
'[%Y-%m-%d %H:%M:%S]',
time.localtime(
time.time()))
created_time = created_time.split('[')[1]
created_time = created_time.split(']')[0]
return created_time
'''
host
user
password
db
port
'''
def __init__(self, host, user, passwd, db, port):
try:
self.db = MySQLdb.connect(
host=host,
user=user,
passwd=passwd,
db=db,
port=port,
charset='utf8')
self.cur = self.db.cursor()
except MySQLdb.Error as e:
print Fore.RED + '连接数据库失败'
print Fore.RED + self.get_current_time(), '[%Y-%m-%d %H:%M:%S]', time.localtime(time.time())
'''
table 表名称
my_dict 要插入的数据,一个有序字典
'''
def insert_data(self, table, my_dict):
try:
cols = ','.join(my_dict.keys())
values = '","'.join(my_dict.values())
values = '"' + values + '"'
try:
# print "table:%s,cols:%s,values:%s." %(table, cols, values)
sql = "insert into %s (%s) values(%s)" % (table, cols, values)
# print "sql:",sql
result = self.cur.execute(sql)
self.db.commit()
if result:
return 1
else:
return 0
except MySQLdb.Error as e:
self.db.rollback()
if "key 'PRIMARY'" in e.args[1]:
print Fore.RED + self.get_current_time(), "数据已存在,未插入数据"
else:
print Fore.RED + self.get_current_time(), "插入数据失败,原因 %d: %s" % (e.args[0], e.args[1])
except MySQLdb.Error as e:
print Fore.RED + self.get_current_time(), "数据库错误,原因%d: %s" % (e.args[0], e.args[1])
def query_data(self,sql):
try:
try:
result = self.cur.execute(sql)
self.db.commit()
if result:
return 1
else:
return 0
except MySQLdb.Error as e:
self.db.rollback()
if "key 'PRIMARY'" in e.args[1]:
print Fore.RED + self.get_current_time(), "数据已存在,未插入数据"
else:
print Fore.RED + self.get_current_time(), "插入数据失败,原因 %d: %s" % (e.args[0], e.args[1])
pass
except MySQLdb.Error as e:
print Fore.RED + self.get_current_time(), "数据库错误,原因%d: %s" % (e.args[0], e.args[1])
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'xxx',
'HOST': '10.x.x5',
'USER': 'wxspider',
'PASSWORD': 'wxxxl235',
'PORT': 3306
}
}
if __name__ == '__main__':
host = DATABASES['default']['HOST']
user = DATABASES['default']['USER']
passwd = DATABASES['default']['PASSWORD']
db = DATABASES['default']['NAME']
port = DATABASES['default']['PORT']
mysql = Mysql(host, user, passwd, db, port)
created_time = mysql.get_current_time()
print created_time
dicts = OrderedDict()
dicts['id']='2'
dicts['name']='python'
tname='test'
# 测试插入数据
result = mysql.insert_data(tname, dicts)
if result:
print Fore.GREEN + "article_table:数据保存成功!"
else:
print Fore.RED + "article_table:数据保存失败!"
sql = 'select * from test'
# 测试查询数据
result = mysql.query_data(sql)
if result:
print Fore.GREEN + ":成功!"
tp = mysql.cur.fetchall()
print type(tp)
print tp
else:
print Fore.RED + ":失败!"
print result

electron Build cross platform desktop apps with JavaScript, HTML, and CSS

快速入门

Electron 可以让你使用纯 JavaScript 调用丰富的原生 APIs 来创造桌面应用。你可以把它看作一个专注于桌面应用的 Node.js 的变体,而不是 Web 服务器。

这不意味着 Electron 是绑定了 GUI 库的 JavaScript。相反,Electron 使用 web 页面作为它的 GUI,所以你能把它看作成一个被 JavaScript 控制的,精简版的 Chromium 浏览器。

主进程

在 Electron 里,运行 package.jsonmain 脚本的进程被称为主进程。在主进程运行的脚本可以以创建 web 页面的形式展示 GUI。

渲染进程

由于 Electron 使用 Chromium 来展示页面,所以 Chromium 的多进程结构也被充分利用。每个 Electron 的页面都在运行着自己的进程,这样的进程我们称之为渲染进程

在一般浏览器中,网页通常会在沙盒环境下运行,并且不允许访问原生资源。然而,Electron 用户拥有在网页中调用 Node.js 的 APIs 的能力,可以与底层操作系统直接交互。

主进程与渲染进程的区别

主进程使用 BrowserWindow 实例创建页面。每个 BrowserWindow 实例都在自己的渲染进程里运行页面。当一个 BrowserWindow 实例被销毁后,相应的渲染进程也会被终止。

主进程管理所有页面和与之对应的渲染进程。每个渲染进程都是相互独立的,并且只关心他们自己的页面。

由于在页面里管理原生 GUI 资源是非常危险而且容易造成资源泄露,所以在页面调用 GUI 相关的 APIs 是不被允许的。如果你想在网页里使用 GUI 操作,其对应的渲染进程必须与主进程进行通讯,请求主进程进行相关的 GUI 操作。

在 Electron,我们提供几种方法用于主进程和渲染进程之间的通讯。像 ipcRendereripcMain 模块用于发送消息, remote 模块用于 RPC 方式通讯。这些内容都可以在一个 FAQ 中查看 how to share data between web pages

打造你第一个 Electron 应用

大体上,一个 Electron 应用的目录结构如下:

1
2
3
4
your-app/
├── package.json
├── main.js
└── index.html

package.json的格式和 Node 的完全一致,并且那个被 main 字段声明的脚本文件是你的应用的启动脚本,它运行在主进程上。你应用里的 package.json 看起来应该像:

1
2
3
4
5
{
"name" : "your-app",
"version" : "0.1.0",
"main" : "main.js"
}

注意:如果 main 字段没有在 package.json 声明,Electron会优先加载 index.js

main.js 应该用于创建窗口和处理系统事件,一个典型的例子如下:

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
const electron = require('electron');
// 控制应用生命周期的模块。
const {app} = electron;
// 创建原生浏览器窗口的模块。
const {BrowserWindow} = electron;
// 保持一个对于 window 对象的全局引用,如果你不这样做,
// 当 JavaScript 对象被垃圾回收, window 会被自动地关闭
let mainWindow;
function createWindow() {
// 创建浏览器窗口。
mainWindow = new BrowserWindow({width: 800, height: 600});
// 加载应用的 index.html。
mainWindow.loadURL(`file://${__dirname}/index.html`);
// 启用开发工具。
mainWindow.webContents.openDevTools();
// 当 window 被关闭,这个事件会被触发。
mainWindow.on('closed', () => {
// 取消引用 window 对象,如果你的应用支持多窗口的话,
// 通常会把多个 window 对象存放在一个数组里面,
// 与此同时,你应该删除相应的元素。
mainWindow = null;
});
}
// Electron 会在初始化后并准备
// 创建浏览器窗口时,调用这个函数。
// 部分 API 在 ready 事件触发后才能使用。
app.on('ready', createWindow);
// 当全部窗口关闭时退出。
app.on('window-all-closed', () => {
// 在 macOS 上,除非用户用 Cmd + Q 确定地退出,
// 否则绝大部分应用及其菜单栏会保持激活。
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
// 在 macOS 上,当点击 dock 图标并且该应用没有打开的窗口时,
// 绝大部分应用会重新创建一个窗口。
if (mainWindow === null) {
createWindow();
}
});
// 在这文件,你可以续写应用剩下主进程代码。
// 也可以拆分成几个文件,然后用 require 导入。

最后,你想展示的 index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
</body>
</html>

运行你的应用

一旦你创建了最初的 main.jsindex.htmlpackage.json 这几个文件,你可能会想尝试在本地运行并测试,看看是不是和期望的那样正常运行。

electron-prebuilt

electron-prebuilt 是一个 npm 模块,包含所使用的 Electron 预编译版本。
如果你已经用 npm 全局安装了它,你只需要按照如下方式直接运行你的应用:

1
electron .

如果你是局部安装,那运行:

1
./node_modules/.bin/electron .

手工下载 Electron 二进制文件

如果你手工下载了 Electron 的二进制文件,你也可以直接使用其中的二进制文件直接运行你的应用。

Windows

1
$ .\electron\electron.exe your-app\

Linux

1
$ ./electron/electron your-app/

macOS

1
$ ./Electron.app/Contents/MacOS/Electron your-app/

Electron.app 里面是 Electron 发布包,你可以在 这里 下载到。

以发行版本运行

在你完成了你的应用后,你可以按照 应用部署 指导发布一个版本,并且以已经打包好的形式运行应用。

参照下面例子

复制并且运行这个库 electron/electron-quick-start

注意:运行时需要你的系统已经安装了 GitNode.js(包含 npm)。

1
2
3
4
5
6
# 克隆这仓库
$ git clone https://github.com/electron/electron-quick-start
# 进入仓库
$ cd electron-quick-start
# 安装依赖库并运行应用
$ npm install && npm start

KaTeX The fastest math typesetting library for the web

KaTeX 简介

examples

demo

1
2
3
4
5
<div class="examples">
<div class="example tex" data-expr="\displaystyle \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} {1+\frac{e^{-8\pi}} {1+\cdots} } } }"></div>
<div class="example tex" data-expr="\displaystyle \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)"></div>
<div class="example tex" data-expr="\displaystyle 1 + \frac{q^2}{(1-q)}+\frac{q^6}{(1-q)(1-q^2)}+\cdots = \prod_{j=0}^{\infty}\frac{1}{(1-q^{5j+2})(1-q^{5j+3})}, \quad\quad \text{for }\lvert q\rvert<1."></div>
</div>

Simple API, no dependencies – yet super-fast on all major browsers.

Fast math typesetting for the web.

  • Fast:
    KaTeX renders its math synchronously and doesn’t need to reflow the page.
  • Print quality:
    KaTeX’s layout is based on Donald Knuth’s TeX, the gold standard for math typesetting.
  • Self contained:
    KaTeX has no dependencies and can easily be bundled with your website resources.
  • Server side rendering:
    KaTeX produces the same output regardless of browser or environment, so you can pre-render expressions using Node.js and send them as plain HTML.

KaTeX supports all major browsers, including Chrome, Safari, Firefox, Opera, and IE 8 - IE 11. A list of supported commands can be on the wiki.

Usage

You can download KaTeX and host it on your server or include the katex.min.js and katex.min.css files on your page directly from a CDN:

1
2
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.js"></script>

In-browser rendering

Call katex.render with a TeX expression and a DOM element to render into:

1
katex.render("c = \\pm\\sqrt{a^2 + b^2}", element);

If KaTeX can’t parse the expression, it throws a katex.ParseError error.

Server side rendering or rendering to a string

To generate HTML on the server or to generate an HTML string of the rendered math, you can use katex.renderToString:

1
2
var html = katex.renderToString("c = \\pm\\sqrt{a^2 + b^2}");
// '<span class="katex">...</span>'

Make sure to include the CSS and font files, but there is no need to include the JavaScript. Like render, renderToString throws if it can’t parse the expression.

Rendering options

You can provide an object of options as the last argument to katex.render and katex.renderToString. Available options are:

  • displayMode: boolean. If true the math will be rendered in display mode, which will put the math in display style (so \int and \sum are large, for example), and will center the math on the page on its own line. If false the math will be rendered in inline mode. (default: false)
  • throwOnError: boolean. If true, KaTeX will throw a ParseError when it encounters an unsupported command. If false, KaTeX will render the unsupported command as text in the color given by errorColor. (default: true)
  • errorColor: string. A color string given in the format "#XXX" or "#XXXXXX". This option determines the color which unsupported commands are rendered in. (default: #cc0000)

For example:

1
katex.render("c = \\pm\\sqrt{a^2 + b^2}", element, { displayMode: true });

Automatic rendering of math on a page

Math on the page can be automatically rendered using the auto-render extension. See the Auto-render README for more information.