工作,学习,生活,这里将会有一些记录. 备用域名:http://meisw.wdlinux.cn 注册 | 登陆
浏览模式: 标准 | 列表分类:区块链

以太坊开发快速上手指南 + 开发相关文章

 

以太坊快速上手指南

在正式开始前,首先推荐过下这篇文章 http://ethfans.org/topics/102
如果你暂时不想了解区块链的技术细节,比如什么工作量证明,公钥加密系统什么的,可以先直接跳过。但还是强烈建议在你对整个开发流程有了点感觉后,把这部分知识补充起来。

区块链部分

http://teahour.fm/2015/12/27/talk-with-jan-about-bitcoin-and-blockchain.html

http://teahour.fm/2016/01/19/talk-with-jan-about-ehtereum.html (文字稿:http://ethfans.org/posts/talk-with-jan-about-ehtereum

编写智能合约

Ethereum提供两种智能合约编程语言SoliditySerpentSolidity的语法类似于JavaScript,而Serpent的语法接近于Python。但也仅仅是语法有点类似,事实上有着巨大的差别,学习时不能简单的代入理解。如果你对编程语言没有偏好,请选择Solidity,也是默认的智能合约编程语言。Solidity文档中文版(正在翻译中,欢迎开发者参与翻译):http://ethfans.org/posts/solidity-content 。

如果不想搭建完整的ethereum开发环境,只是想了解下Solidity,可以看下这个项目:Browser-Solidity

常用辅助工具和开发环境

以太坊的开发生态正在日益完善,相比刚发布时的裸写,现在已经有很多开发工具供选择了。

以太坊本地私有链开发环境搭建教程(中文) : http://ethfans.org/posts/ethereum-private-network-bootstrap

Đapp

通常你都是在写一个面向最终用户的应用,这时你需要一个界面。以太坊的开发者通常使用Web App + Smart Contract的方式来搭建这样的应用,并称之为Đapp(Decentralised Application)。在这里,智能合约部分的代码就相当于BS架构中的服务器代码,而Web部分则相当于前端代码。Web部分可以使用你熟悉的的HTML + JavaScript + CSS 来完成,然后通过JSONRPC的方法使用以太坊客户端提供的API接口,来操作你部署在区块链上的智能合约,这里区块链就相当于你租用的一台云服务器,所以有时候我们可以把以太坊的区块链理解为全球共享的一台World Computer。

Đapp最为关键的就是如何进行JSONRPC调用,以太坊官方提供了一个工具: Web3.js。如果你开发Đapp, 就必然需要使用它。

如何搭建一个测试网络并运行一个简单的 dapp http://ethfans.org/topics/85

以太坊本地私有链开发环境搭建

 ethereum-bootstrap是我建立的一个github项目,目的是帮助刚接触以太坊的同学快速的搭建起自己的本地开发环境,体验智能合约的开发。阅读本文需要有基本的编程知识。项目地址: https://github.com/janx/ethereum-bootstrap

Ethereum Bootstrap

通过本文所述方法和项目中的脚本,我们可以快速的搭建好自己的私链进行开发测试。

仓库中包含的工具有:

  • 一个测试账户导入脚本,在首次部署时将五个测试账户私钥导入以太坊节点。
  • 一个genesis.json配置文件,为对应的五个测试账户提供初始资金(以太币),方便开发测试。
  • 一个快速启动私有链节点并进入交互模式的脚本。
  • 一个合约样例:contracts/Token.sol。这是一个使用合约语言Solidity编写的智能合约。Token合约的功能是发行一种token(可以理解为货币,积分等等),只有合约的创建者有发行权,token的拥有者有使用权,并且可以自由转账。

测试账户私钥是放在Github上的公开数据,千万不要用于正式环境中或者公有链上。如果在测试环境之外的地方使用这些私钥,你的资金将会被窃取!

准备

  1. 在本地安装好go-ethereumsolc, 可以执行gethsolc命令。如果操作系统是ubuntu, 安装官方的ethereum安装包即可。
  2. 将本仓库通过git clone命令下载到本地。
  3. 安装expect,工具脚本用它来自动化一些过程。例如在ubuntu上: sudo apt-get install expect

启动geth

  1. 进入本仓库目录: cd ethereum-bootstrap
  2. 导入测试账户私钥: ./bin/import_keys.sh
  3. 启动私有链节点: ./bin/private_blockchain.sh. 启动成功后可以看到类似如下输出: 
  4. 此时以太坊交互式控制台已经启动,我们可以开始测试和开发了。

注意:工具脚本假设你的geth安装在默认位置, 可以直接通过geth执行。如果geth命令安装在非标准的位置,可以设置GETH环境变量指定geth可执行文件的路径。例如:

GETH=/some/weird/dir/geth ./bin/import_keys.sh

使用以太坊控制台编译和部署智能合约

contracts目录下有一个智能合约样例文件Token.sol, 通过Solidity语言实现了基本的代币功能, 合约持有者可以发行代币, 使用者可以互相转账.

我们可以使用以太坊控制台来编译部署这个合约.以太坊控制台是最基本的工具,使用会比较繁琐.社区也提供了其他更加方便的部署工具,此处不做讨论.

第一步,我们先把合约代码压缩为一行.新建一个ssh session, 切换到geth用户环境su - geth, 然后输入:cat contracts/Token.sol | tr '\n' ' '.

切换到以太坊控制台,把合约代码保存为一个变量:

var tokenSource = 'contract Token {     address issuer;     mapping (address => uint) balances;      event Issue(address account, uint amount);     event Transfer(address from, address to, uint amount);      function Token() {         issuer = msg.sender;     }      function issue(address account, uint amount) {         if (msg.sender != issuer) throw;         balances[account] += amount;     }      function transfer(address to, uint amount) {         if (balances[msg.sender] < amount) throw;          balances[msg.sender] -= amount;         balances[to] += amount;          Transfer(msg.sender, to, amount);     }      function getBalance(address account) constant returns (uint) {         return balances[account];     } }';

然后编译合约代码:

var tokenCompiled = web3.eth.compile.solidity(tokenSource);

通过tokenCompiled.Token.code可以看到编译好的二进制代码,通过tokenCompiled.Token.info.abiDefinition可以看到合约的ABI

接下来我们要把编译好的合约部署到网络上去.

首先我们用ABI来创建一个javascript环境中的合约对象:

var contract = web3.eth.contract(tokenCompiled.Token.info.abiDefinition);

我们通过合约对象来部署合约:

var initializer = {from: web3.eth.accounts[0], data: tokenCompiled.Token.code, gas: 300000};  var callback = function(e, contract){     if(!e) {       if(!contract.address) {         console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");       } else {         console.log("Contract mined!");         console.log(contract);       }     } };  var token = contract.new(initializer, callback);

contract.new方法的第一个参数设置了这个新合约的创建者地址from, 这个新合约的代码data, 和用于创建新合约的费用gasgas是一个估计值,只要比所需要的gas多就可以,合约创建完成后剩下的gas会退还给合约创建者.

contract.new方法的第二个参数设置了一个回调函数,可以告诉我们部署是否成功.

contract.new执行时会提示输入钱包密码.执行成功后,我们的合约Token就已经广播到网络上了.此时只要等待矿工把我们的合约打包保存到以太坊区块链上,部署就完成了.

在公有链上,矿工打包平均需要15秒,在私有链上,我们需要自己来做这件事情.首先开启挖矿:

miner.start(1)

此时需要等待一段时间,以太坊节点会生成挖矿必须的数据,这些数据都会放到内存里面.在数据生成好之后,挖矿就会开始,稍后就能在控制台输出中看到类似:

:hammer:Mined block

的信息,这说明挖到了一个块,合约已经部署到以太坊网络上了!此时我们可以把挖矿关闭:

miner.stop(1)

接下来我们就可以调用合约了.先通过token.address获得合约部署到的地址, 以后新建合约对象时可以使用.这里我们直接使用原来的contract对象:

// 本地钱包的第一个地址所持有的token数量 > token.getBalance(web3.eth.accounts[0]) 0  // 发行100个token给本地钱包的第一个地址 > token.issue.sendTransaction(web3.eth.accounts[0], 100, {from: web3.eth.accounts[0]}); I1221 11:48:30.512296   11155 xeth.go:1055] Tx(0xc0712460a826bfea67d58a30f584e4bebdbb6138e7e6bc1dbd6880d2fce3a8ef) to: 0x37dc85ae239ec39556ae7cc35a129698152afe3c "0xc0712460a826bfea67d58a30f584e4bebdbb6138e7e6bc1dbd6880d2fce3a8ef"  // 发行token是一个transaction, 因此需要挖矿使之生效 > miner.start(1) :hammer:Mined block > miner.stop(1)  // 再次查询本地钱包第一个地址的token数量 > token.getBalance(web3.eth.accounts[0]) 100  // 从第一个地址转30个token给本地钱包的第二个地址 > token.transfer.sendTransaction(web3.eth.accounts[1], 30, {from: web3.eth.accounts[0]}) I1221 11:53:31.852541   11155 xeth.go:1055] Tx(0x1d209cef921dea5592d8604ac0da680348987b131235943e372f8df35fd43d1b) to: 0x37dc85ae239ec39556ae7cc35a129698152afe3c "0x1d209cef921dea5592d8604ac0da680348987b131235943e372f8df35fd43d1b" > miner.start(1) > miner.stop(2) > token.getBalance(web3.eth.accounts[0]) 70 > token.getBalance(web3.eth.accounts[1]) 30

其他

私有链的所有数据都会放在仓库根目录下的data目录中,删除这个目录可以清除所有数据,重新启动新环境。

做完这些之后你应该对在以太坊私有链上进行开发有了一个大概的了解吧,如果还想学习更多知识,一可以看一看上面执行的脚本代码,到底干了些什么,用了哪些命令行参数,二可以阅读正在ethfans上更新的solidity文档中文版

 

http://ethfans.org/posts/ethereum-private-network-bootstrap

如何搭建一个测试网络并运行一个简单的 dapp

对于开发者而言,在一个新平台上开发应用之前,一个可控的测试环境是必不可少的。
对于普通用户而言,在正式的链上开始使用钱包转账,在etherex挂单等等严肃操作之前,先在一个demo程序上熟悉下功能,也能减少出错概率。

以太坊作为一个“去中心化的应用平台”,也确实给搭建测试网络提供了很多便利。以下我们就一步一步的介绍如何搭建一个测试链,并在测试链上运行ethereum.org上的hello world程序。

准备工作

  1. 安装geth
  2. 如果你准备连接到我在阿里云上的testnet, 下载这个创世块
  3. 如果你要搭建自己的testnet,可以参照这里的格式创建创世块

开始

  • 首先打开你的终端输入如下命令启动geth
geth --bootnodes "enode://7cc0c2e8abd944d6bee8966fc21b0597de27ef912614ff1b7b4f2c51b7d72078d05038435686f8821aa7ce6918a6065192368bb05cd50a908ed2f8958dfa7197@115.29.32.87:30303" --datadir "YOURTESTNETDATADIR" --genesis "EXAMPLEGENESIS.json"  --networkid 12345 --nodiscover console
  • 当屏幕上出现这样的文字后 modules: admin:1.0 db:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 shh:1.0 txpool:1.0 web3:1.0 你就进入了以太坊的命令行控制界面

  • 在以太坊的命令行界面输入如下命令创建一个新的账户

personal.newAccount('ethfans')
  • 加入阿里云上我搭建的testnet node(如果你搭建一个人的testnet,不需要这一步)
admin.addPeer("enode://7cc0c2e8abd944d6bee8966fc21b0597de27ef912614ff1b7b4f2c51b7d72078d05038435686f8821aa7ce6918a6065192368bb05cd50a908ed2f8958dfa7197@115.29.32.87:30303")

然后输入admin.peers检查是否已添加成功远程节点, 添加失败的话会返回null

  • 开始挖矿(第一次挖矿需要生成一个2G的DAG文件,耗时10分钟左右,具体时长取决于电脑性能)
miner.start()

待续

etherenum钱包安装

 etherenum钱包安装

https://github.com/ethereum/go-ethereum/archive/v1.5.4.tar.gz
 
 geth
geth -datadir "D:ethereum"
geth account new
geth account list
geth wallet import
geth console
 
get attach
net.listening
net.peerCount
admin.peers
admin.nodeInfo
eth.blockNumber
eth.accounts
 
创建用户:
personal.newAccount("111111")
其中参数为此账户的密码。
也可以先创建账户,然后输入密码:
personal.newAccount()
 
查看账户余额
其中参数为区块链地址
eth.getBalance("0x7d1f7be4112ce63b9de04a0bf95c1e87e430bd1b")
eth.getBalance(eth.accounts[0])
 
personal.unlockAccount(eth.accounts[0], '123456')
 
启动挖矿
miner.start()
miner.stop()
 
首先,输入geth console,回车。
方法一:
然后,解锁账户。输入personal.unlockAccount(addr, passwd, duration),addr是你的地址,passwd是账户密码,duration是账户处于解锁状态的时间,例如300表示在300秒内无需再次解锁。建议在记事本中写完此命令,复制到geth中。成功解锁账户,界面会返回 true。
 
 
testrpc. 用geth可以创建一个测试网络,另一种更快的创建测试网络的方法是使用testrpc. Testrpc可以在启动时帮你创建一堆存有资金的测试账户。它的运行速度也更快因此更适合开发和测试。你可以从testrpc起步,然后随着合约慢慢成型,转移到geth创建的测试网络上 - 启动方法很简单,只需要指定一个networkid:geth --networkid "12345"。这里是testrpc的代码仓库,下文我们还会再讲到它。
 

快速同步以太坊区块链:Geth长期节点连接方法

为了帮助国内的同学们以最快的速度同步以太坊的区块链,EthFans社区建立了一个长期节点,地址为:

enode://91922b12115c067005c574844c6bbdb114eb262f90b6355cec89e13b483c3e4669c6d63ec66b6e3ca7a3a462d28edb3c659e9fa05ed4c7234524e582a8816743@120.27.164.92:13333设置为默认连接节点

如果你是geth用户,可以做如下设置,默认连接这个节点:
  • 找到你的data目录,例如linux上默认是~/.ethereum
  • 在data目录里面新建一个static-nodes.json文件,输入以下内容并保存:
    ["enode://91922b12115c067005c574844c6bbdb114eb262f90b6355cec89e13b483c3e4669c6d63ec66b6e3ca7a3a462d28edb3c659e9fa05ed4c7234524e582a8816743@120.27.164.92:13333"]
  • 如常启动geth即可

检查是否连接成功

  • 通过geth console进入控制台,或者通过geth --ipcpath ~/.ethereum/geth.ipc attach开控制台挂上当前进程
  • 控制台中输入:admin.peers.forEach(function(p) {console.log(p.network.remoteAddress);})
  • 如果打印出的地址里面包括120.27.164.92, 说明已经连上
更多连接设置可以参考文档: [color=rgb(0, 105, 214) !important]https://github.com/ethereum/go-ethereum/wiki/Connecting-to-the-network
链接该节点的第二个方法:
首先,用geth命令打开命令行钱包,然后新建一个终端窗口,输入命令 geth attach。
然后,在新窗口中输入命令行admin.addPeer("enode://91922b12115c067005c574844c6bbdb114eb262f90b6355cec89e13b483c3e4669c6d63ec66b6e3ca7a3a462d28edb3c659e9fa05ed4c7234524e582a8816743@120.27.164.92:13333"),enter键。
最后,检查是否连接成功。输入命令行 admin.peers,enter键。查看列出的节点中有没有上面的节点。
参考文档:[color=rgb(0, 105, 214) !important]https://ethereum.gitbooks.io/frontier-guide/content/connecting.html

 

http://ethfans.org/topics/150

比特币基本概念

 

椭圆曲线数字签名算法

椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线对数字签名算法(DSA)的模拟,该算法是构成比特币系统的基石。

私钥

非公开,拥有者需安全保管。通常是由随机算法生成的,说白了,就是一个巨大的随机整数,256位、32字节。大小介于1 ~ 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141之间的数,都可以认为是一个合法的私钥。于是,除了随机方法外,采用特定算法由固定的输入,得到32字节输出的算法就可以成为得到私钥的方法。于是,便有了迷你私钥(Mini Privkey),原理很简单,例如,采用SHA256的一种实现:

private key = SHA256()

迷你私钥存在安全问题,因为输入集合太小,易被构造常见组合的彩虹表暴力破解,所以通常还是使用系统随机生成的比较好,无安全隐患。

公钥

公钥与私钥是相对应的,一把私钥可以推出唯一的公钥,但公钥却无法推导出私钥。公钥有两种形式:压缩与非压缩。

早期比特币均使用非压缩公钥,现大部分客户端已默认使用压缩公钥。这个貌似是比特币系统一个长得像feature的bug,早期人少活多代码写得不够精细,openssl库的文档又不足够好,导致Satoshi以为必须使用非压缩的完整公钥,后来大家发现其实公钥的左右两个32字节是有关联的,左侧(X)可以推出右侧(Y)的平方值,有左侧(X)就可以了。

现在系统里两种方式共存,应该会一直共存下去。两种公钥的首个字节为标识位,压缩为33字节,非压缩为65字节。以0×04开头为非压缩,0×02/0×03开头为压缩公钥,0×02/0×03的选取由右侧Y开方后的奇偶决定。

压缩形式可以减小Tx/Block的体积,每个Tx Input减少32字节。

签名

使用私钥对数据进行签署(Sign)会得到签名(Signature)。通常会将数据先生成Hash值,然后对此Hash值进行签名。签名(signature)有两部分组成: R + S。由签名(signature)与Hash值,便可以推出一个公钥,验证此公钥,便可知道此签名是否由公钥对应的私钥签名。

通常,每个签名会有三个长度:73、72、71,符合校验的概率为25%、50%、25%。所以每次签署后,需要找出符合校验的签名长度,再提供给验证方。

地址

地址是为了人们交换方便而弄出来的一个方案,因为公钥太长了(130字符串或66字符串)。地址长度为25字节,转为base58编码后,为34或35个字符。base58是类似base64的编码,但去掉了易引起视觉混淆的字符,又在地址末尾添加了4个字节校验位,保障在人们交换个别字符错误时,也能够因地址校验失败而制止了误操作。

由于存在公钥有两种形式,那么一个公钥便对应两个地址。这两个地址都可由同一私钥签署交易。

公钥生成地址的算法:

Version = 1 byte of 0 (zero); on the test network, this is 1 byte of 111
Key hash = Version concatenated with RIPEMD-160(SHA-256(public key))
Checksum = 1st 4 bytes of SHA-256(SHA-256(Key hash))
Bitcoin Address = Base58Encode(Key hash concatenated with Checksum)

下图是非压缩公钥生成地址的过程:

6290a5ea-f93a-11e2-9ac4-835e86a38642

对于压缩公钥生成地址时,则只取公钥的X部分即可。

推导关系

三者推导关系:私钥 >> 公钥 >> 两个地址。过程均不可逆。拥有私钥便拥有一切,但通常为了方便,会把对应的公钥、地址也存储起来。

交易

比特币的交易(Transation,缩写Tx),并不是通常意义的交易,例如一手交钱一手交货,而是转账。交易由N个输入和M个输出两部分组成。交易的每个输入便是前向交易的某个输出,那么追踪到源头,必然出现一个没有输入的交易,此类交易称为CoinBase Tx。CoinBase类交易是奖励挖矿者而产生的交易,该交易总是位于Block块的第一笔。

7c9c862e-f61b-11e2-9dfe-324d025e5dd3

拥有一个输入与输出的Tx数据:

Input:
Previous tx: f5d8ee39a430901c91a5917b9f2dc19d6d1a0e9cea205b009ca73dd04470b9a6
Index: 0
scriptSig: 304502206e21798a42fae0e854281abd38bacd1aeed3ee3738d9e1446618c4571d10
90db022100e2ac980643b0b82c0e88ffdfec6b64e3e6ba35e7ba5fdd7d5d6cc8d25c6b241501

Output:
Value: 5000000000
scriptPubKey: OP_DUP OP_HASH160 404371705fa9bd789a2fcd52d2c580b65d35549d
OP_EQUALVERIFY OP_CHECKSIG
一旦某个Tx的第N个输出成为另一个Tx的输入,那么该笔比特币即为已花费。每个交易有唯一Hash字符串来标识,通过对交易数据做两次SHA256哈希运算而来:

Tx Hash ID = SHA256(SHA256(Tx Data))

矿工费

矿工费(Transaction Fee)是鼓励矿工将Tx打包进Block的激励报酬。计算一笔交易的矿工费:

Transaction Fee = SUM(Input’s amount) – SUM(Output’s amount)
每笔Tx的矿工费必然大于等于零,否则该笔Tx即为非法,不会被网络接收。

数据块

数据块(Block)是存储Block Meta与Tx的地方。Block的第一笔Tx总是CoinBase Tx,因此Block中的交易数量总是大于等于1,随后是这段时间内网络广播出来的Tx。

找到合适的Block是一件非常困难的事情,需要通过大量的数学计算才能发现,该计算过程称为“挖矿”。首个发现者,会得到一些比特币作为奖励。

数据链

多个Block连接起来成为数据链(Block Chain)。

94b6ba76-f621-11e2-95b0-febc373535b7

为了引入容错与竞争机制,比特币系统允许Block Chain出现分叉,但每个节点总是倾向于选择最高的、难度最大的链,并称之为Best Chain,节点只认可Best Chain上的数据。

首个Block称为Genesis Block,并设定高度为零,后续每新增一个Block,高度则递增一。目前是不允许花费Genesis Block中的比特币的。

每个Block中的Tx在此Block中均唯一
一个Tx通常只会在一个Block里,也可能会出现在多个Block中,但只会在Best Chain中的某一个Block出现一次

货币存储

比特币是密码货币、纯数字化货币,没有看得见摸得着的硬币或纸币。一个人持有比特币意味着:

其拥有一些地址的私钥
这些地址是数笔交易的输出,且未花费
所有货币记录均以交易形式存储在整个blockchain数据块中,无交易无货币。货币不会凭空产生,也不会凭空消失。遗失了某个地址的私钥,意味着该地址上的Tx无法签署,无法成为下一个Tx的输入,便认为该笔比特币永久消失了。

货币发行

既然所有交易的输入源头都是来自CoinBase,产生CoinBase时即意味着货币发行。比特币采用衰减发行,每四年产量减半,第一个四年每个block的coinbase奖励50BTC,随后是25btc, 12.5btc, …并最终于2140年为零,此时总量达到极限为2100万个btc。

153fcb3e-f621-11e2-8322-0b2f2f425ef7

减半周期,严格来说,并不是准确的四年,而是每生成210000个block。之所以俗称四年减半,是因为比特币系统会根据全网算力的大小自动调整难度系统,使得大约每两周产生2016个block,那么四年约21万块block。

该函数GetBlockValue()用于计算挖得Block的奖励值:

int64 static GetBlockValue(int nHeight, int64 nFees)
{
int64 nSubsidy = 50 * COIN;

// Subsidy is cut in half every 210000 blocks, which will occur approximately every 4 years
nSubsidy >>= (nHeight / 210000);

return nSubsidy + nFees;
}
当达到2100万btc以后,不再有来自CoinBase的奖励了,矿工的收入来源仅剩下交易的矿工费。此时,每个block的收入绝对值btc很低,但此时比特币应当会非常繁荣,币值也会相当的高,使得矿工们依然有利可图。

杜绝多重支付

传统货币存在多重支付(Double Spending)问题,典型的比如非数字时代的支票诈骗、数字时代的信用卡诈骗等。在比特币系统里,每笔交易的确认均需要得到全网广播,并收录进Block后才能得到真正确认。每笔钱的花销,均需要检测上次输入交易的状态。数据是带时间戳的、公开的,BlockChain由巨大的算力保障其安全性。所以比特币系统将货币的多重支付的风险极大降低,几近于零。通过等待多个Block确认,更是从概率上降低至零。一般得到6个确认后,可认为非常安全。但对于能影响你人生的重大支付,建议等待20~30个确认。

匿名性

任何人均可以轻易生成大量的私钥、公钥、地址。地址本身是匿名的,通过多个地址交易可进一步提高匿名性。但该匿名性并不像媒体宣传的那样,是某种程度上的匿名。因为比特币的交易数据是公开的,所以任何一笔资金的流向均是可以追踪的。

不了解比特币的人为它的匿名性产生一些担忧,比如担心更利于从事非法业务;了解比特币的人却因为它的伪匿名性而苦恼。传统货币在消费中也是匿名的,且是法律保障的,大部分国家都不允许个人涂画纸币。

地址本身是匿名的,但你可以通过地址对应的私钥签名消息来向公众证明你拥有某个比特币地址。

作者:Kevin

区块链地址生成算法

 地址是为了人们交换方便而弄出来的一个方案,因为公钥太长了(130字符串或66字符串)。地址长度为25字节,转为base58编码后,为34或35个字符。base58是类似base64的编码,但去掉了易引起视觉混淆的字符,又在地址末尾添加了4个字节校验位,保障在人们交换个别字符错误时,也能够因地址校验失败而制止了误操作。

由于存在公钥有两种形式,那么一个公钥便对应两个地址。这两个地址都可由同一私钥签署交易。
公钥生成地址的算法:

Version = 1 byte of 0 (zero); on the test network, this is 1 byte of 111 Key hash = Version concatenated with RIPEMD-160(SHA-256(public key)) Checksum = 1st 4 bytes of SHA-256(SHA-256(Key hash)) Bitcoin Address = Base58Encode(Key hash concatenated with Checksum)

下图是非压缩公钥生成地址的过程:

对于压缩公钥生成地址时,则只取公钥的X部分即可。

推导关系

三者推导关系:私钥 >> 公钥 >> 两个地址。过程均不可逆。拥有私钥便拥有一切,但通常为了方便,会把对应的公钥、地址也存储起来。

-----------------------以下来源于百度http://zhidao.baidu.com/link?url=-iAaP8yzPO7NI4ruKOtmowXhR4FONK5cdx7IqFWkHuCwA8XFt9I82LOlGAGoJko06gQxs5qI0lKtvr8ndC0Qp76eW0rg_lx7CTf9FVyaF2u ---------------
比特币地址的生成过程

(说明: 有些数字以"0x"开头,意思是此数字使用十六进制表示法。"0x"本身没有任何含义,它是C语言流传下来的,约定俗成的写法,比如0xA就是十进制的10。另外,1个字节 = 8位二进制 = 2位十六进制)。

第一步,随机选取一个32字节的数、大小介于1 ~ 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141之间,作为私钥。
18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725

第二步,使用椭圆曲线加密算法(ECDSA-secp256k1)计算私钥所对应的非压缩公钥。 (共65字节, 1字节 0x04, 32字节为x坐标,32字节为y坐标)关于公钥压缩、非压缩的问题另文说明。

0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B
23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6

第三步,计算公钥的 SHA-256 哈希值
600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408

第四步,取上一步结果,计算 RIPEMD-160 哈希值
010966776006953D5567439E5E39F86A0D273BEE

第五步,取上一步结果,前面加入地址版本号(比特币主网版本号“0x00”)
00010966776006953D5567439E5E39F86A0D273BEE

第六步,取上一步结果,计算 SHA-256 哈希值
445C7A8007A93D8733188288BB320A8FE2DEBD2AE1B47F0F50BC10BAE845C094

第七步,取上一步结果,再计算一下 SHA-256 哈希值(哈哈)
D61967F63C7DD183914A4AE452C9F6AD5D462CE3D277798075B107615C1A8A30

第八步,取上一步结果的前4个字节(8位十六进制)
D61967F6

第九步,把这4个字节加在第五步的结果后面,作为校验(这就是比特币地址的16进制形态)。
00010966776006953D5567439E5E39F86A0D273BEED61967F6

第十步,用base58表示法变换一下地址(这就是最常见的比特币地址形态)。

16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM

------------------------------来自于以太坊黄皮书-------------------------------------------------------
以太坊地址生成算法


------------------------------来自于以太坊白皮书------------------------------------------------------------------------
https://github.com/ethereum/wiki/wiki/White-Paper#ethereum-accounts

Ethereum Accounts

In Ethereum, the state is made up of objects called "accounts", with each account having a 20-byte address and state transitions being direct transfers of value and information between accounts. 
以太坊中,账户包含20字节的地址,以及账户之间价值和信息的传递的状态转换。

An Ethereum account contains four fields:
The nonce, a counter used to make sure each transaction can only be processed once
The account's current ether balance
The account's contract code, if present
The account's storage (empty by default)
以太坊账户包含4个部分:
nonce 是一个计数器用于确保每笔交易只被处理一次
账户当前以太币数量
合约代码
以太坊存储空间?

"Ether" is the main internal crypto-fuel of Ethereum, and is used to pay transaction fees. 
以太币是以太坊中的主要密码货币,用于支付交易费用

In general, there are two types of accounts: externally owned accounts, controlled by private keys, and contract accounts, controlled by their contract code. An externally owned account has no code, and one can send messages from an externally owned account by creating and signing a transaction; in a contract account, every time the contract account receives a message its code activates, allowing it to read and write to internal storage and send other messages or create contracts in turn.
以太坊中有两种账户:外部用户的账户,通过私钥控制;智能合约账户,通过合约代码控制。
外部用户账户不包含代码,用户可以通过创建和签署交易来给外部用户账户发送信息。
合约账户,每次接受到信息时,合约代码开始工作,允许读取、写入内部存储,已结发送信息,或者反过来创建合约。

Note that "contracts" in Ethereum should not be seen as something that should be "fulfilled" or "complied with"; rather, they are more like "autonomous agents" that live inside of the Ethereum execution environment, always executing a specific piece of code when "poked" by a message or transaction, and having direct control over their own ether balance and their own key/value store to keep track of persistent variables.
注意以太坊中的合约不应该被视为某种可以被完成,被遵守的恭喜。它们更像是以太坊环境的自治代理机构。能够直接控制它们的以太币和秘钥来追踪持续变量。

区块链匿名技术

 2.1 Darkcoin

Darkcoin使用的匿名技术是:Darksend引入了Coinjoin分布式混币服务。Coinjoin的混币,分析者有可能通过输入地址的金额和输出地址的金额对比,分析出混币的输入和输出地址对。另外Darksend不开源,有纪录混币历史的可能性;

而暗网币的环签名则是块链上的混币服务,这种混币具有相同金额的输入,并且使用了多个别人的公钥,只知道是从这一群人中的一个发送的,但无法判断是哪一个,也无法通过金额分析来判断输入输出对。暗网币还支持TOR和TRR技术,引入了隐身地址,比Darkcoin的匿名性强。

2.2 Zerocoin/Zerocash

Zerocoin是一种去中心化的混币技术,把一定数量如1个比特币转化为zerocoin,采用零知识证明技术花费zerocoin或转化为其他zerocoin,使得在零币之中的交易不可追踪。Zerocoin是一种全新匿名技术,但远远未到实用阶段,原因如下:
(1)性能问题,zerocoin零知识证明,至少占45KB空间和450ms的验证时间(128位的密钥长度),必须全网广播和存贮,并且由每个节点验证,将带来巨大的块链长度和验证时间。
(2) Zerocoin的局限性。Zerocoin不能用来支付,不能拆分金额,不能隐藏金额,可以通过金额对比来获得混币输入和输出地址的对应关系。

Zerocash是Zerocoin的升级版本,使用密码学承诺,把零知识证明所需容量减少了97.7%,把验证速度减少了98.6%,可以用来支付,输入金额可变,可以隐藏输入金额,比Zerocoin先进了许多。

Zerocoin/Zerocash存在两个致命问题。第一是它们的初始数据定义,必须定义一个数N,由P和Q两个质数相乘得到,如果N足够大,别人就无法推断出P和Q,也就无法双花。但初始生成人不能保存P和Q值,否则可以随意双花,而且无法检测。但是无法验证P和Q是否被保存了。第二个问题是,Zerocoin/Zerocash的开发团队由政府官方资助,这很让人担心。

2.3 Bytecoin

Bytecoin是最早引入环签名和隐身地址的加密货币。暗网币就是在Bytecoin基础之上进行开发和创新的。Bytecoin不支持Tor,通讯未加密,无法隐匿上网地址,容易被协议监听,从而分析钱包地址和IP地址的对应关系。
Bytecoin是命令行钱包,使用上不方便,暗网币有图形化钱包、即将推出在线钱包、手机钱包和轻钱包。
Bytecoin没有块链应用,仅为匿名而匿名。我们认为匿名技术是一个基础技术,在其上发展多种应用如P2P兑换所、块链商城等,才有可能让匿名币更广泛地被用户所接受。
2.4其他币种
Anoncoin:仅支持Tor和另一个匿名网络i2p。
Blackcoin:未采用匿名技术,并非匿名币。
Moreno:与Bytecoin一样支持环签名和隐身地址,在Bytecoin基础上发展了GPU挖矿。
Boolberry来自Bytecoin,一样支持环签名和隐身地址,但不支持TOR和TRR,没有任何匿名应用。
StealthCoin:通过StealthSend采用环签名,正在研发中。

XCurrency:通讯加密,支持环签名,不支持隐身地址。

Records:271234