从"什么是区块链"到一个小时内构建区块链

区块链是记录的数字账本, 以称作区块的块状数据排列. 这些区块随后通过称为哈希函数的加密验证相互链接.这些区块连在一起形成一个连续的链 - 区块链.
这种类型的数据结构对加密货币等有用的原因是去中心化. 去中心化意味着链中的记录不存储在任何单一的位置, 这些记录每个人都可以访问, 并且任何一方都不可以改变.

应用
尽管区块链通常会让人联想到比特币, 但该技术有很多用途.有几大类的区块链应用程序, 其中包括:
货币和数字资产
组成比特币的区块链将资金发送给全球的个体和商家.但区块链也可以创建数字资产, 如股票和债券.
可验证的数据和合约
区块链可以创建任何数据, 文件或合约的可验证记录.这对于任何使用大数据的行业(如医疗行业或政府)都很有用.
了解代码
在开始之前, 我想指出本文假设你对编程有一个基本的了解, 并对计算机科学理论有一定的了解.
这篇文章并不是包罗万象的, 而是为那些希望扩展技术知识的人介绍区块链编程.
我相信真正理解一个概念的最好方法就是付诸实践.如果你有兴趣了解如何实现一个区块链合约, 我将在下面编写一个简单易行的分步教程.
你将使用以太坊来制作一份智能合约.以太坊是一个内建了图灵完备的编程语言的区块链, 这意味着它可以运行应用程序为任何可计算的问题建模(只要运行时间和内存允许).在开始之前, 请务必熟悉以下以太坊术语:
账户是以太坊的基本单元或对象. 区块链跟踪每个帐户的状态. 有两种类型的帐户: 外部拥有帐户(EOA, Externally Owned Accounts )(由人类用户控制)和合约帐户(由其内部合约代码控制并可由外部拥有帐户激活).
"智能合约(Smart Contract)"或"去中心化应用(DApp, Decentralized Application)"由合约账户中的代码确定, 当EOA将交易发送至合约账户时, 该合约账户将被激活.合约账户由外部EOA触发, 以产生一个被所有看到它的节点都接受的应答.
每个帐户最多包含四个字段:
- 随机数(Nonce, 用于确保每次交易只发生一次的计数器)
- 以太平衡
- 合约代码
- 存储
交易是一个存储从账户间发送的消息的已签名的数据包.它包含以下数据字段:
- 接受者
- 签名
- 以太转移量
- 数据
以太是以太坊的加密货币(ETH / USD = ~$50, 按当天的汇率换算), 每当在以太坊上进行一次动作时, 以太就会兑换成一笔费用.

为了降低恶意交易的风险, 例如分布式拒绝服务(DDoS, Distributed Denial of Service)攻击, 以太坊会对每一笔通过它执行的交易收取费用.
那么谁收取这些费用?有些节点称为矿工, 这些矿工收取费用以验证和执行所有交易.矿工将交易分组成区块, 然后可以将其添加到区块链中.
现在你已经对以太坊的工作原理有了一个基本的了解, 是时候开始了.
请注意, 我使用的是Ubuntu Linux, 但这也适用于其他Linux发行版以及MacOS(含Homebrew)和 Windows 10(使用你的终端和最新稳定版本).命令行工具和安装技术的完整列表可以在这里找到.
制作区块链
安装geth
首先你需要从PPA安装以太坊.在你的终端中, 运行以下命令:
sudo apt-get install -y software-properties-common sudo add-apt-repository -y ppa:ethereum/ethereum sudo apt-get update sudo apt-get install -y ethereum
现在你可以通过创建一个新目录并写入一个json文件来创建一个初始块(genesis block):
cd mkdir eth-new cd eth-new nano genesis.json
接下来, 将以下代码粘贴到json文件中以创建初始块:
{ "nonce": "0x0000000000000042", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "difficulty": "0x4000", "alloc": {}, "coinbase": "0x0000000000000000000000000000000000000000", "timestamp": "0x00", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "Custem Ethereum Genesis Block", "gasLimit": "0xffffffff" }
按下Ctrl + X, Y, 回车保存这个新的生成块文件.
创建区块链
下面创建区块链, 将maxpeers命令设置为0以禁用网络.
mkdir eth-data geth --datadir eth-new genesis.json init eth-new/genesis.json --networkid 123 --nodiscover --maxpeers 0 console
在geth控制台中, 键入以下内容以创建一个新帐户并输入任何你想要的内容创建一个新密码.你将必须输入你的新密码两次.
personal.newAccount()
之后的输出应该是一串字母和数字 -- 你帐户的地址.将该地址保存在某处并通过输入"exit"并按回车键退出.
发送以太到你的帐户
你需要重新打开生成初始块文件.键入以下内容:
nano genesis.json
在"alloc"那个花括号中, 粘贴你先前保存的帐户地址.继续操作, 并给自己一笔以太的款项. 在下面的"balance"旁边显示的金额等于10以太.
{ "nonce": "0x0000000000000042", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "difficulty": "0x4000", "alloc": { "0x09c7b615a1c5b3016ff6b521723364aa9382ec6e": { "balance": "10000000000000000000" } }, "coinbase": "0x0000000000000000000000000000000000000000", "timestamp": "0x00", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "Custem Ethereum Genesis Block", "gasLimit": "0xffffffff" }
完成更新后, 使用Ctrl + X, Y, 回车保存文件.
删除旧的区块链并创建一个新的区块链
执行这些命令清除旧的区块链数据并重新启动geth:
cd eth-data rm -rf chaindata dapp history nodekey cd .. geth --datadir eth-new genesis.json --networkid 123 --nodiscover --maxpeers 0 console
在geth控制台中, 键入以下命令:
> primary = eth.accounts[0] > web3.fromWei(eth.getBalance(primary), "ether")
你的地址和你的10以太的余额将会出现.
开始挖矿( Mining)
为了有一个工作区块链, 你需要创建矿工. 要做到这一点, 请通过键入"exit"并按回车键退出geth控制台.
要开始挖矿, 请执行以下命令:
geth --mine --datadir eth-data --networkid 123 --nodiscover --> maxpeers 0 console 2>>geth.log
Geth现在就开始.如前所述, 你已经创建了一位收取以太费用的矿工.输入以下命令以查看你的余额:
> primary = eth.accounts[0] > balance = web3.fromWei(eth.getBalance(primary), "ether")
你现在应该拥有比以前更多的以太.
安装Solc
你正在使用的以太坊合约将使用Solidity编写. 你必须安装Solc编译器才能使用Solidity. 为此, 请打开一个新终端并输入以下内容:
bash sudo add-apt-repository ppa:ethereum/ethereum
出现一条消息, 提示说"Press ENTER to continue.(按ENTER键继续)"按下回车, 然后键入以下内容:
sudo apt-get update sudo apt-get install solc -y which solc
你需要记住将要输出的Solc的路径. 返回到显示geth控制台的终端窗口. 执行这些命令, 将\<path>更改为返回给你的路径:
admin.setSolc("<path>") eth.getCompilers()
对第二个命令的回应是"Solidity", 它告诉我们你现在已拥有Solc并可以使用Solidity.
了解欢迎(greeter)合约
下面是一个带有添加的评论的简单合约代码, 代码是从Sams Class取过来并修改的.它包含两种类型的合约.第一种是凡人合约, 指定一个合约可以由撰写合约的人来处理掉, 并且需要将合约声明为合约, 因为合约默认为永存的.第二个是欢迎合约, 将打印出一个小问候.
contract mortal { /* Define var owner of the type address*/ /* 定义address类型的变量owner*/ address owner;
/* this function sets the owner of the contract */ /* 此函数设置了合约的主人 */ function mortal() { owner = msg.sender; }
/* Function to recover fees */ /* 收回费用的函数 */ function kill() { if (msg.sender == owner) selfdestruct(owner); } }
contract greeter is mortal { /* define variable greeting type*/ /* 定义变量 greeting 的类型*/ string greeting;
/* this runs when the contract is executed */ /* 当合约运行时执行以下函数 */ function greeter(string _greeting) public { greeting = _greeting; }
/* main*/ /* 主函数 */ function greet() constant returns (string) { return greeting; } }
解锁你的帐户
开始一个合约需要花费以太费用, 因此你需要解锁你的账户.你可以通过输入以下内容来完成此操作:
primary = eth.accounts[0] personal.unlockAccount(primary)
并输入你的密码.一旦你看到输出"true
", 你就知道你已经成功地解锁了你的账户.
编译你的合约
在geth控制台中, 从先前的一行没有注释的代码中复制并粘贴合约的整个源代码:
var greeterSource = 'contract mortal { address owner; function mortal() { owner = msg.sender; } function kill() { if (msg.sender == owner) suicide(owner); } } contract greeter is mortal { string greeting; function greeter(string _greeting) public { greeting = _greeting; } function greet() constant returns (string) { return greeting; } }'
这将返回"undefined
(未定义)".
在geth控制台中, 键入以下内容:
> var greeterCompiled = web3.eth.compile.solidity(greeterSource)
这次的回应又是"undefined
", 如下所示.
准备部署合约
现在你已拥有你的凡人合约和欢迎合约, 你将需要定义问候语并实例化你的帐户对象.这将需要更多的以太.
在geth控制台中, 粘贴这些命令:
var _greeting = "Hello World!" var greeterContract = web3.eth.contract(greeterCompiled.greeter.info.abiDefinition);
var greeter = greeterContract.new(_greeting, {from: eth.accounts[0], data: greeterCompiled.greeter.code, gas: 1000000}, 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! Address: " + contract.address); console.log(contract); }
} })
出现"Contract transaction send(合约交易发送)"消息, 几秒钟后, 你会看到一条消息: "Contract mined! (合约已开采! )"
测试合约
以下命令将首先返回一个长地址, 然后返回你的问候语.
eth.getCode(greeter.address) greeter.greet()

当你看到这个欢迎语, 你已经创建了你的第一个婴儿期的区块链程序.做得好!
原文发布时间为:2018-03-02
本文作者:Mr.Crypto
本文来源:腾讯云 云+社区,如需转载请联系原作者。