一、区块链

1. 分布式去中心化

比特币设计的初衷就是要避免依赖中心化的机构,没有发行机构,也不可能操纵发行数量。既然没有中心化的信用机构,在电子货币运行的过程中,也势必需要一种机制来认可运行在区块链上的行为(包括比特币的运营,亦或是运行在区块链上的其他业务),这种机制就是共识机制。在完全去中心化的区块链上运行的比特币,采用的是PoW(Proof of Work,工作量证明),该机制完美的解决了拜占庭将军问题(存在异常的情况下仍能达成一致)。因为基础网络架构为分布式,对单独一个节点是无法控制或破坏整个网络,掌握网内51%的运算能力(非节点数)才有可能操作交易,而这个代价大概要超过270亿美元。

2. 无须信任

整个区块链网络中的数据是公开透明的,每个节点(参与者)都可自由加入该网络中,下载到所有的数据。任意两个节点间的数据交换无需互相信任,完全依靠区块链中的交易历史和数据的可追溯,以及共识机制来保证数据交换的正确且不可逆的执行。

3. 不可篡改和加密安全性

跟当前银行网银系统(特别是公司网银系统)的加密机制类似,区块链的数据结构和交易流程中大量的使用了公私钥来加解密,保证数据的安全性。基于该技术基础,甚至可以应用群组签名来保证共有数据的安全性。任何事物既然有优点,也同时会存在不足之处。根源于分布式网络架构和共识机制,在区块链上运行的交易确认时间会比较长(比特币的确认时间大概是15分钟),交易并发数受限(比特币的每秒交易数为7笔,而淘宝的每秒并发数能达到10万左右),区块的容量限制(当前为1M,区块链的扩容一直在讨论中),监管难以介入,基于工作量证明的共识机制存在浪费系统资源和带宽的问题。

4. 区块链技术

a. 区块

区块是一个包含在区块链(公开账簿)里的聚合了交易信息的容器。它由一个包含元数据的区块头和紧跟其后的构成区块主体的一长串交易组成。区块头是80字节,而平均每个交易至少是250字节,而且平均每个区块至少包含超过500个交易。
区块结构如下图

交易(Tx)详情中的结构如下图

b. 区块链

当一个节点从网络接受到传入的区块时,它会验证这些区块,然后链接到现有的区块链上,链接的形态如下图:

由于每个区块包含前一个区块的HASH值,这就使得从创世块到当前块形成了一条块链,每个区块必定按时间顺序跟随在前一个区块之后,因为如果不知道前一块区块的HASH值就没法生成当前区块。要改变一个已经在块链中存在一段时间的区块,从计算上来说是不可行的,因为如果它被改变,它之后的每个区块必须随之改变。这些特性使得双花比特币非常困难,区块链是比特币的最大创新。

5. 比特币钱包

a. 比特币钱包的生成

  1. 首先使用随机数发生器生成一个 私钥 。一般来说这是一个256bits的数,拥有了这串数字就可以对相应 钱包地址 中的比特币进行操作,所以必须被安全地保存起来。
  2. 私钥经过SECP256K1算法处理生成了公钥。SECP256K1是一种椭圆曲线算法,通过一个已知私钥时可以算得公钥,而公钥已知时却无法反向计算出私钥。这是保障比特币安全的算法基础。
  3. 同SHA256一样,RIPEMD160也是一种Hash算法,由公钥可以计算得到公钥哈希,而反过来是行不通的。
  4. 将一个字节的地址版本号连接到公钥哈希头部(对于比特币网络的pubkey地址,这一字节为“0”),然后对其进行两次SHA256运算,将结果的前4字节作为公钥哈希的校验值,连接在其尾部。
  5. 将上一步结果使用BASE58进行编码(比特币定制版本),就得到了钱包地址。

流程图如下

b .转账

比特币钱包间的转账是通过交易(Transaction)实现的。交易数据是由转出钱包私钥的所有者生成,也就是说有了私钥就可以花费该钱包的比特币余额。生成交易的过程如下:

  1. 交易的原始数据包括“转账数额”和“转入钱包地址”,但是仅有这些是不够的,因为无法证明交易的生成者对“转出钱包地址”余额有动用的权利。所以需要用私钥对原始数据进行签名。
  2. 生成“转出钱包公钥”,这一过程与生成钱包地址的第2步是一样的。
  3. 将“转出签名”和“转出公钥”添加到原始交易数据中,生成了正式的交易数据,这样它就可以被广播到比特币网络进行转账了。

二、以太坊Ethereum

1. 概念

a. 什么是以太坊

简单来说,以太坊是一种新的法律形式。现行法律的本质是一种合约。它是由(生活于某一社群的)人和他们的领导者之间所缔结的,一种关于彼此该如何行动的共识。个体之间也存在着一些合约,这些合约可以理解为一种私法,相应的,这种私法仅对合约的参与者生效。

例如,你和一个人订立合约,借给他一笔钱,但他最后毁约了,不打算还这笔钱。此时你多半会将对方告上法庭。在现实生活中,打官司这种事情常常混乱不堪并且充满了不确定性。将对方告上法庭,也通常意味着你需要支付高昂的费用聘请律师,来帮你在法庭上针对法律条文展开辩论,而且这一过程一般都旷日持久。而且,即使你最终赢了官司,你依然可能会遇到问题(比如,对方拒不执行法庭判决)。
令人欣慰的是,当初你和借款人把条款写了下来,订立了合约。但法律的制定者和合约的起草者们都必须面对一个不容忽视的挑战:那就是,理想情况下,法律或者合约的内容应该是明确而没有歧义的,但现行的法律和合约都是由语句构成的,而语句,则是出了名的充满歧义。
因此,一直以来,现行的法律体系都存在着两个巨大的问题:首先,合约或法律是由充满歧义的语句定义的,第二,强制执行合约或法律的代价非常大。
而以太坊,通过数字货币和编程语言的结合,解决了现行法律体系的这两大问题。
以太坊系统自身带有一种叫做以太币(Ether)的数字货币。以太币和著名的数字货币比特币(Bitcoin)有着非常多的相似之处。两者均为数字储值货币,且无法伪造,都以去中心化的方式运行来保证货币供应不被某一方所控制。两者都可以像电子邮件一样,作为货币自由地在全世界流通。而且,由于它们可以做到传统货币做不到的事情,因此用户对它们未来的价值充满期待 。

另外
1.详情请阅读以太坊白皮书 (中文, 英文)。
2.以太坊教程

b. 基本知识

  • 公钥加密系统。 Alice有一把公钥和一把私钥。她可以用她的私钥创建数字签名,而Bob可以用她的公钥来验证这个签名确实是用Alice的私钥创建的,也就是说,确实是Alice的签名。当你创建一个以太坊或者比特币钱包的时候,那长长的0xdf…5f地址实质上是个公钥,对应的私钥保存某处。类似于Coinbase的在线钱包可以帮你保管私钥,你也可以自己保管。如果你弄丢了存有资金的钱包的私钥,你就等于永远失去了那笔资金,因此你最好对私钥做好备份。
  • 点对点网络。 就像BitTorrent, 以太坊分布式网络中的所有节点都地位平等,没有中心服务器。
  • 区块链。 区块链就像是一个全球唯一的帐簿,或者说是数据库,记录了网络中所有交易历史。
  • 以太坊虚拟机(EVM)。 它让你能在以太坊上写出更强大的程序(比特币上也可以写脚本程序)。它有时也用来指以太坊区块链,负责执行智能合约以及一切。
  • 节点。 你可以运行节点,通过它读写以太坊区块链,也即使用以太坊虚拟机。完全节点需要下载整个区块链。轻节点仍在开发中。
  • 矿工。 挖矿,也就是处理区块链上的区块的节点。这个网页可以看到当前活跃的一部分以太坊矿工:stats.ethdev.com。
  • 工作量证明。 矿工们总是在竞争解决一些数学问题。第一个解出答案的(算出下一个区块)将获得以太币作为奖励。然后所有节点都更新自己的区块链。所有想要算出下一个区块的矿工都有与其他节点保持同步,并且维护同一个区块链的动力,因此整个网络总是能达成共识。(注意:以太坊正计划转向没有矿工的权益证明系统(POS),不过那不在本文讨论范围之内。)
  • 以太币。 缩写ETH。一种你可以购买和使用的真正的数字货币。这里是可以交易以太币的其中一家交易所的走势图。在写这篇文章的时候,1个以太币价值65美分。
  • Gas. 在以太坊上执行程序以及保存数据都要消耗一定量的以太币,Gas是以太币转换而成。这个机制用来保证效率。
  • DApp. 以太坊社区把基于智能合约的应用称为去中心化的应用程序(Decentralized App)。DApp的目标是(或者应该是)让你的智能合约有一个友好的界面,外加一些额外的东西,例如IPFS(可以存储和读取数据的去中心化网络,不是出自以太坊团队但有类似的精神)。DApp可以跑在一台能与以太坊节点交互的中心化服务器上,也可以跑在任意一个以太坊平等节点上。这里分享一个以太坊DApp教程,可以高效的学习如何开发一个DApp,很适合入门。

2. 工作流程

a. 环境搭建

建议使用Mac OS环境,不然可能会出现各种坑。

  1. 安装NodeJS,安装Python。
  2. 安装testrpc(测试环境中使用),安装go-ethereum(真实环境中使用)。
  3. 安装solc。
  4. 安装truffle。

如果是windows的话建议用工具ethbox可以一键安装以太坊开发环境的工具: ethbox

b. Solidity语言简介

下面是官网上面的一段关于智能投票合约的示例代码

  contract Ballot {//一个选民的构造体struct Voter {uint weight; // 权重(即他可以投几票)bool voted;  //是否已经投过票address delegate; // 代表地址(他可以代表某个人进行投票)uint vote;   // index of the voted proposal}// 投票的提案的构造体struct Proposal{bytes32 name;   // 提案名称uint voteCount; //获得的票数}address public chairperson;//会议主席//地址 -选民 的mapmapping(address => Voter) public voters;// 投票种类的动态数组Proposal[] public proposals;///构造函数function Ballot(bytes32[] proposalNames) {chairperson = msg.sender;//初始化会议主席voters[chairperson].weight = 1;//初始化所有的提案for (uint i = 0; i < proposalNames.length; i++) {proposals.push(Proposal({name: proposalNames[i],voteCount: 0}));}}// 给予投票权function giveRightToVote(address voter) returns (bool b) {if (msg.sender != chairperson || voters[voter].voted) {//对于会议主席和已经投过票的选民这里不处理return false;;}voters[voter].weight = 1;return true;}/// 投票权转移函数function delegate(address to) {// 投票权转移的发起人Voter sender = voters[msg.sender];if (sender.voted)throw;//递归找到没有转移投票权的  选民while (voters[to].delegate != address(0) &&voters[to].delegate != msg.sender) {to = voters[to].delegate;}if (to == msg.sender) {throw;}//将发起人设置为已经投过票的状态sender.voted = true;//将代表设置为刚才递归获取的选民sender.delegate = to;Voter delegate = voters[to];if (delegate.voted) {//如果代表已经投过票就在他投票的提案的票数增加proposals[delegate.vote].voteCount += sender.weight;}else {//将代表的的票数增加delegate.weight += sender.weight;}}/// 投票函数function vote(uint proposal) {Voter sender = voters[msg.sender];if (sender.voted)throw;sender.voted = true;sender.vote = proposal;//将投的提案票数增加proposals[proposal].voteCount += sender.weight;}///获得票数最多的提案function winningProposal() constantreturns (uint winningProposal){uint winningVoteCount = 0;for (uint p = 0; p < proposals.length; p++) {if (proposals[p].voteCount > winningVoteCount) {winningVoteCount = proposals[p].voteCount;winningProposal = p;}}}
}

解读

  • address. 地址类型。chairperson是会议主席的钱包地址。这个地址会在合约的构造函数function Ballot()中被赋值。很多时候也称呼这种地址为’owner’(所有人)。
  • public. 这个关键字表明变量可以被合约之外的对象使用。private修饰符则表示变量只能被本合约(或者衍生合约)内的对象使用。如果你想要在测试中通过web3.js使用合约中的某个变量,记得把它声明为public。
  • Mapping或数组。mapping(address => Voter)为选民钱包地址和选民构造体的键值对。Proposal[] public proposals是一个提案构造体的数组。
  • 有特殊的变量和函数总是在全局命名空间存在,主要用于提供有关blockchain信息,例如msg,block,tx,其中msg.sender为发起人的地址。

solidity语言更深入的理解可以阅读官方文档。

c. 使用geth部署合约

  1. 启动一个测试节点

geth –testnet –fast –cache=512 –genesis CustomGenesis.json console

这里的CustomGenesis.json是为了给测试的账户分配以太币

{"coinbase": "0x0000000000000000000000000000000000000000","difficulty": "0x20000","extraData": "","gasLimit": "0x2fefd8","nonce": "0x0000000000000042","mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000","parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000","timestamp": "0x00","alloc": {"0xe49c283bc6bf92c5833cc981b97679238dd3b5da": {"balance": "111111111000000000000000000000000000"},"0xd8927c296b3ebe454a6409770a0c323ec4ed23ba": {"balance": "222222222000000000000000000000000000"}}
}

solc下的内容要替换成你的测试账户地址。具体geth的用法请查看官方文档和源码介绍。

  1. 使用solc编译智能合约,获得二进制代码
    例如以下代码
contract test { function multiply(uint a) returns(uint d) { return a * 7; }
}

在geth中输入

source = “contract test { function multiply(uint a) returns(uint d) { return a * 7; } }”

clientContract = eth.compile.solidity(source).test

编译返回的结果的JSON格式如下

其中,

  • code:编译后的EVM字节码
  • info:编译器返回的metadata
  • abiDefination:Application Binary Interface定义。具体接口规则参见这里
  • compilerVersion:编译此代码的solidity编译器版本
  • developerDoc:针对开发者的Natural Specification Format,类似于Doxygen
  • language:合约语言
  • languageVersion:合约语言版本
  • source:源代码
  • userDoc:针对用户的Ethereum的Natural Specification Format。

编译器返回的JSON结构反映了合约部署的两种不同的路径。info信息真实的存在于区中心化的云中,作为metadata信息来公开验证Blockchain中合约代码的实现。而code信息通过创建交易的方式部署到区块链中。

  1. 使用solc编译智能合约,获得二进制代码
    部署合约前,确保你有一个解锁的账户并且账户中有余额,因为部署合约得过程中会消耗以太币。输入web3.fromWei(eth.getBalance(eth.accounts[0]),”ether”)可以查看账户余额。
    解锁一个账户

personal.unlockAccount(eth.accounts[0])

获得账户

primaryAddress = eth.accounts[0]

定义一个abi (abi是个js的数组,否则不成功)

abi = [{ constant: false, inputs: [{ name: ‘a’, type: ‘uint256’ } ]}]

创建智能合约

MyContract = eth.contract(abi)

发送交易部署合约

contract = MyContract.new({from: primaryAddress, data:”0x6060604052602a8060106000396000f3606060405260e060020a6000350463c6888fa18114601a575b005b6007600435026060908152602090f3”})

如果交易被pending,如图说明你的miner没有在挖矿

启动一个矿工
miner.setEtherbase(eth.primaryAddress) //设定开采账户
miner.start(8)

eth.getBlock(“pending”, true).transactions
这时候发现交易已经在区块中

不过会发现,交易还是pending,这是因为该交易区块没有人协助进行运算验证,这时候只需要再启动一个矿工就行了
miner.start(8)

  1. 与合约进行交互

Multiply7 = eth.contract(clientContract.info.abiDefinition);
var myMultiply7 = Multiply7.at(contract.address);
myMultiply7.multiply.call(3)

myMultiply7.multiply.sendTransaction(3, {from: contract.address})

d. 使用truffle框架

使用truffle部署智能合约的步骤:

  1. truffle init (在新目录中) => 创建truffle项目目录结构,
  2. 编写合约代码,保存到contracts/YourContractName.sol文件。
    例如Ballot .sol,此时要找到migrations文件夹,在deploy_contracts.js文件中添加deployer.deploy(Ballot);
  3. truffile compile 编译合约代码。
  4. 启动以太坊节点(例如在另一个终端里面运行testrpc)。
  5. truffle migrate(在truffle项目目录中)。

1. 编写单元测试

test文件夹中新建ballot.js文件

contract('Ballot',function(accounts)){//accounts是所以账户得数值it("获取投票权",function(){var meta = Ballot.deployed();return meta.giveRightToVote(accounts[1]).then(function(b){assert.equal(Boolean(b),true,"获取投票权失败");});});}

在项目根目录下运行truffle test,你应该看到测试通过,如果使用自己构造的ballot对象,可以这样写:

contract('Ballot',function(accounts)){//accounts是所以账户得数值it("获取投票权",function(){var proposals = [];proposals.push("proposal0");Ballot.new(proposals).then(function(meta){return meta.giveRightToVote(accounts[1]).then(function(b){assert.equal(Boolean(b),true,"获取投票权失败");});});});}
  • 合约中发送以太币。 this是合约实例的地址,以变接下来检查这个地址的余额(或者直接使用this.balance)
  • 当你通过web3.js调用交易函数时(使用web3.eth.sendTransaction),交易并不会立即执行。事实上交易会被提交到矿工网络中,交易代码直到其中一位矿工产生一个新区块把交易记录进区块链之后才执行。因此你必须等交易进入区块链并且同步回本地节点之后才能验证交易执行的结果。用testrpc的时候可能看上去是实时的,因为测试环境很快,但是正式网络会比较慢。
  • Gas. (译注:以太坊上的燃料,因为代码的执行必须消耗Gas。直译为汽油比较突兀,故保留原文做专有名词。)直到现在我们都没有涉及Gas的概念,因为在使用testrpc时通常不需要显式的设置。当你转向geth和正式网络时会需要。在交易函数调用中可以在{ from: , value: , gas: _ } 对象内设置Gas参数。Web3.js提供了web3.eth.gasPrice调用来获取当前Gas的价格,Solidity编译器也提供了一个参数让你可以从命令行获取合约的Gas开销概要:solc –gas YouContract.sol.

2. 为合约创建一个界面

app目录中,可以编写自己的html和js文件,js与智能合约的交互与单元测试基本一致,例如一个界面上有一个输入框和一个按钮,获得选民的投票权。

<!DOCTYPE html>
<html>
<head><title>Ballot App</title><link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'><link href="./app.css" rel='stylesheet' type='text/css'><script src="./app.js"></script>
</head>
<body><h1>Ballot</h1><h2>Example Truffle Dapp</h2><br><h1>Send</h1><br><label for="amount">Account:</label><input type="text" id="account" placeholder="e.g., 0x453468394hdfg84858345348"></input><br><br><button id="getRightVote" onclick="getRight()">Get Right Vote</button><br><br><span id="status"></span>
</body>
</html>

app.js中的代码为

function getRight() {var account = document.getElementById("account").value;var meta = Ballot.deployed();meta.giveRightToVote(account).then(function(b){if(Boolean(b)){setStatus("Get Right Vote Success");}else{setStatus("Get Right Vote Error");}}).catch(function(e){setStatus("Get Right Vote Error");console.log(e);});};

另外分享几个教程给大家:

  • python以太坊,主要是针对python围绕web3.py进行区块链以太坊应用开发的讲解。
  • web3j,主要是针对java和android程序员围绕web3j库进行区块链以太坊开发的讲解。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和事件等内容。
  • 以太坊开发,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • 以太坊教程,主要介绍智能合约与dapp应用开发,适合入门。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和事件等。

以太坊教程:入门学习开发以太坊dapp相关推荐

  1. 【python教程入门学习】Python实现自动玩贪吃蛇程序

    这篇文章主要介绍了通过Python实现的简易的自动玩贪吃蛇游戏的小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学一学 实现效果 先看看效果 这比我手动的快多了,而且是单机的,自动玩没惹 ...

  2. 【python教程入门学习】普通人学python有意义吗

    普通人学python有意义吗?普通人能不能学习python语言,难不难,是否容易上手,学了python能做那些事情,能挣多少钱?这些问题是很多同学关心的问题,今天python教程入门学习就从小白同学的 ...

  3. 【python教程入门学习】学python要多久,0基础学python有多难

    学python要多久,0基础学python有多难,这是很多想学习python语言同学绕不开的问题,都害怕花完钱最终没有应有的回报!对于毫无经验0基础的同学来说学习python什么最重要,方向选对坚持下 ...

  4. 【python教程入门学习】第一个Pygame程序

    Pygame 作为一个入门级的游戏开发库,其实并不难学,只要掌握 Python 编程的相关知识就能很轻松地掌握它. Pygame 语法简单.明了,秉持了 Python 语言一贯的风格.同时,它作为一个 ...

  5. 【python教程入门学习】python能做什么

    python能做什么?[python教程入门学习]介绍,最近许多的朋友咨询,听说python很火,甚至可以超越JAVA,因此很想学这个python,但是不知道python能做什么,能完成一些什么项目呢 ...

  6. 【python教程入门学习】Python新年炫酷烟花秀代码

    先介绍下 Pygame 绘制烟花的基本原理,烟花从发射到绽放一共分为三个阶段: 1,发射阶段:在这一阶段烟花的形状是线性向上,通过设定一组大小不同.颜色不同的点来模拟"向上发射" ...

  7. 【python教程入门学习】Python扑克牌21点游戏实例代码

    大家好,本篇文章主要讲的是Python扑克牌21点游戏实例代码,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览 废话还是说太多了 直接上代码 | `import` `random ...

  8. proteus8单片机c语言仿真教程,入门学习Proteus 8仿真软件以及C51单片机的LED点亮(C语言)——实例...

    入门学习Proteus 8仿真软件以及C51单片机LED的点亮(C语言)--实例 一.点亮LED的程序编译 1.打开Keil uVision 4新建一个工程 2.在Atmel下寻找AT89C52芯片并 ...

  9. 【python教程入门学习】Python 集成开发环境(IDE): VS Code

    "工欲善其事必先利其器"中的"器",对于一个程序员来说就是编辑器.编译器(或解释器).调试器等工具,这些器具(工具)帮助我们快速的写出程序,运行程序和解决其中的 ...

最新文章

  1. 阿里巴巴年度技术总结:人工智能在搜索的应用和实践
  2. 对字符串数组排序,使所有变位词都相邻(C++)
  3. html发送十六进制字符数组,十六进制数组怎么转换成字符串数组?
  4. duilib获取字符串的像素长
  5. Windows消息传递机制详解
  6. mcrypt拓展_【PHP】Mcrypt 扩展模块安装及使用
  7. Membership学习(一) Membership介绍[xgluxv]
  8. bypass功能介绍
  9. Java之spring新手教程(包教包会)
  10. 贪吃蛇程序设计报告python_C某贪吃蛇程序设计报告.doc
  11. ws2812 c语言程序,STC15单片机驱动WS2812B七彩LED(汇编混合编程)
  12. clamav查杀病毒
  13. 【前端春招】前端春招实习+秋招心路历程
  14. 如何重新设置苹果id密码_苹果怎么设置下载软件不要密码?手机技巧分享
  15. js制作的炫酷3D太阳系行星运行效果
  16. @PersistenceContext 注解在spring中代理
  17. 有源阻尼抑制LCL滤波器固有谐振
  18. 8个 Chatbot 框架介绍
  19. 时间在一分一秒的流逝着
  20. 2020年中国对外直接投资行业发展综述及发展趋势分析[图]

热门文章

  1. C语言中‘/n’和‘\n’(写项目时发现)
  2. CSS_10_三大定位机制
  3. 基于SSM的高校餐厅防疫管理系统
  4. 2021年中国移动K歌用户规模及用户规模结构分析:全民K歌月均活跃用户数居榜首[图]
  5. kali怎么安装python3_kali下python安装pwntools工具 | kTWO-个人博客
  6. linux恢复rm命令,linux下rm删除与恢复
  7. I hate Regex and 正则表达式可视化
  8. 驱动程序无法使用安全套接字层(SSL)加密与sql server建立安全连接
  9. J - Cardinal Adjacencies
  10. ExcelUtils--excel报表模板引擎