搭建私有区块链链专业课程平台怎么选

查看: 6015|回复: 11
私有区块链技术更适合于银行应用
论坛徽章:6
区块链(Blockchain)是一个去中心化的数据库,是一串使用密码学方法相关联产生的数据块,每一个数据块中包含了一次网络交易的信息,用于验证其信息的有效性(防伪)和生成下一个区块。简而言之,就是分布记账、多点清算的分布式记账系统。它的特点是去中心化、开放性、自治性、信息不可篡改、匿名性以及溯源性,这些技术特征也很符合银行IT业的发展趋势。
但对银行来说,区块链技术有着不可逾越的现实屏障,这主要表现在:
区块链技术不适用于银行国际业务
这主要表现在两点:一是区块链技术削弱了央行的地位,二是区块链技术无法实现汇率定价,这两点都对经济主权产生了不利影响,因此它不可能被应用于国际业务。
央行的职能包括:金融调控职能(如制定和执行货币政策)、公共服务职能(如:向政府融资等)、金融监管职能(如:对各类金融机构业务活动进行监管;监督管理金融市场等)。实现这些职能依赖于国家级的集中清算机制。通过国家集中清算,央行可以根据货币总量与货币乘数计算出M1,M2等货币数量指标,据此制定和调整货币政策,稳定经济运行。同样,只有通过集中清算,才能体现央行为商业银行背书的职能。这点与区块链技术中去中心化思想完全不符,甚至是背道而驰。
长期来看,影响汇率的主要因素主要有:相对价格水平、和限额、对本国商品相对于外国商品的以及生产率。简单而言,汇率定价取决于国家之间的经济总量之比。试想一下,在区块链技术应用下没有中央清算,怎样核算经济总量?无法核算经济总量,自然无法制定汇率,更不要谈借助汇率调整本国经济发展态势。因此,区块链技术并不适用于跨国业务。
区块链技术不适用于跨行业务
区块链技术不适用于跨行业务,这点和银行使用公有云的顾虑是一样的。去中心化和分布记账,意味着本行账目公开于它行,本行客户信息公开于它行,本行产品信息也要公开于它行,这显然是不现实的。
既然区块链技术无法适用于跨国业务和跨行业务,那么私有区块链技术是否适合于本行内应用系统环境哪?答案是肯定的。
私有区块链技术符合银行IT系统去核心系统中心化的趋势
众所周知,银行IT系统建设正在快速去核心系统化:由“全行统一账簿”转换为“多账簿分别记账、总账系统统一核算”的方式。在这一转换过程中,实现总账系统与多系统账簿之间统一、近实时过账是技术关键,这点正是区块链技术中去中心化的技术优势所在。
当年,银行核心系统大集中的一个重要目标是:实现全行一本帐,杜绝假账错帐漏账。现在去核心系统中心化,就必须解决“没有全行一本帐,依然可以杜绝假账错帐漏账”的问题。区块链技术的“不可篡改”和“可追溯性”两大优势,刚好满足了这一要求。
私有区块链技术对供应链贷款业务有很大帮助
既往业务过程中,供应链贷款业务需要对借款人与上下游企业之间的业务过程进行监控,比如跟踪仓单和销售单据等。为此,银行的银企直连系统与借款人的ERP系统需要对接,并实现数据同步,才能将同步结果应用于借款人征信与贷后跟踪。
如借助区块链技术的不可篡改性和可追溯性优势,实现银企直连系统与借款人ERP系统之间数据实时同步、分布记账,那么对提升信贷质量的帮助作用显而易见。
区块链技术并非新技术,ESB系统的基本原理与之相似,去IOE所依赖的分布式计算技术也与它有很大相似之处,因此,运用私有区块链技术对银行IT部门并没有很大的技术瓶颈。相信随着时间的延伸,私有区块链技术在银行应该是可以有所作为的。
论坛徽章:6
原创文章,欢迎讨论。
论坛徽章:6
跨境不好做,境内跨行还是可以的吧?人行找帮人,做个自己的算法,把央行的认证检查啥的加到算法里。。。。
本人不懂区块链详细技术,纯粹YY啊
求职 : 论坛徽章:168
论坛徽章:3
本帖最后由 Snelgar 于
11:26 编辑
区块链技术的一大应用场景正是跨境支付与结算,可以减少中间环节,实现点对点交易,降低交易费用。
& && &美国的Ripple公司已经利用区块链技术开发了一个没有中央节点的分布式支付网络,期望取代SWIFT成为全球统一支付网络,目前已有17个国家的银行加入合作了。英国的Circle公司也于今年1月获得首张电子货币牌照,正致力于通过比特币后台网络的区块链技术发展C2C跨境支付平台,允许客户在美元与英镑之间进行实时转账。 Chain、Ethereum、IBM、Microsoft也在利用区块链技术发展跨境支付与结算应用。
& && &基于本人对区块链技术有限的了解,暂时对区块链的分布式账簿容量持有疑问,对于跨境支付或是任意一个清算网络内,当交易量级呈指数级增长,如何保证分布式账簿的容量不会爆盘,同时还要保证数据同步的正确性和实时性。(比特币是有2100万枚的上限的,不知道比特币的设计者制定这个上限时是否已经预见了我所提及的问题)欢迎大神批评指正。
论坛徽章:7
顶!!!!如此好贴,,,版里就缺这个
论坛徽章:0
呵呵,好文,没人理
论坛徽章:0
之前也请了一个台湾的专家宣讲区块链,后来也没动静了。。。
论坛徽章:0
楼主和5楼,2位朋友,期待你们的继续分享
认证徽章论坛徽章:0
讨论中。。。。楼主不错。
itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有    
 北京市公安局海淀分局网监中心备案编号:10 广播电视节目制作经营许可证:编号(京)字第1149号区块链学堂(第三课):以太坊生产网络/测试网络/私有网络+Geth 搭建私有网络实战_巴比特_服务于区块链创新者
区块链学堂(第三课):以太坊生产网络/测试网络/私有网络+Geth 搭建私有网络实战
要理解以太坊 PrivateNetwork 先要理解以太坊的两种官方网络,目前以太坊官方提供了两种网络:
生产环境网络
测试网络 TestNet
下面将分别简单讲解下这两种网络。
以太坊生产网络
以太坊的生产网络顾名思义,也就是产生真正有价值的 的以太币的网络。 目前生产网络目前已经生成了300万以上的区块,还在持续生成中。挖矿挖出来的每个以台币在10美金以上。 生产环境下的以太坊状态时如此的(截图自)
生产环境网络优点
全球化的,部署在Internet环境上的,
智能合约的代码,执行,区块的调用,都可以清晰的查看到。
部署在生产环境上的智能合约,全世界任何应用都可以调用
任何合约执行都会消耗真实的以太币,也就是真实的现金。不适合开发、调试和测试,
所有节点是全球化的,速度较慢
且对于部分商业应用来说,只需要一部分节点,例如分布式部署的10-20台服务器即可。而不需要遍布全球的网络。
以太坊测试网络 TestNet
以太坊的测试网络也是官方提供的,顾名思义就是专供用户来开发、调试和测试的。 上面的合约执行不消耗真实的以太币。也就是不花钱
所以如果开发简单的智能合约的话,用测试网络也就足够了,用户可以把更多的精力集中在智能合约的编写上。
但因为网络是官方提供的,因此对于以太坊技术的底层实现、Geth的各种参数接口、整个以太坊的技术真实性能的理解就会弱很多。所以从开发的角度来说,一个更好的选择是Private Network,可以从技术的底层去深入理解以太坊。
测试环境网络优点
合约执行不消耗真实货币
全球化的,部署在Internet环境上的,
智能合约的代码,执行,区块的调用,都可以清晰的查看到。
部署在测试环境上的智能合约,全世界任何应用都可以调用
所有节点是全球化的,速度较慢
测试网络不可能作为商业应用的实际落地环境
以太坊私有网络 PrivateNetwork
以太坊的私有网络,顾名思义就是由用户自己通过Geth创建的私有网络,是一个非常适合开发、调试和测试的网络
方便开发者深入理解以太坊的技术底层
因为节点相对较少,速度较快
用户可以随时创建,随时销毁,随时重建一个以太坊网络
随意的增加节点数目,或者删除节点,
既可以在服务器上建立,也可以在自己的windows或者Mac机器上建立,
甚至一台机器可以建立多个节点,在一台机器上实现多节点的私有网络。
因为不是全球化的,只有在私有网络内的节点才能查看智能合约的执行、调用等。
下一章讲解:实战搭建私有网络!
在本章中我们将实战如何使用Geth,如何搭建以太坊的私有网络。
之前说过Geth是三种实现以太坊协议的工具之一,由于Geth是官方推崇的以及个人精力有限,对于另外两种工具的搭建私有网络,请参考网上资料。
下面的Geth实战,在MacBook上实现,对于Windows方面,比较类似。
Step 1: 建立目录和genesis.json
在命令行模式创建一个目录,例如tmpPrivate
创建文件genesis.json, 并填入如下内容。
"nonce": "0x0042",
"timestamp": "0x0",
"parentHash": "0x0000",
"extraData": "0x0",
"gasLimit": "0x",
"difficulty": "0x1",
"mixhash": "0x0000",
"coinbase": "0x3333",
"alloc": {
用户可以vim,也可以用其他编辑器如sublime等,个人推荐使用Atom
Atom 官网地址:
Atom 是一个由谷歌支持发布的文本编辑器, 一个你可以自定义做任何事情的现代编辑器,后面涉及文件和代码演示会主要在Atom上执行。
创建完成后,在Atom中,本文件夹下应该只有一个genesis.json
Step 2: 执行命令,创建创世区块
切换回命令行,执行命令,制造创世区块
geth --datadir "./" init genesis.json
执行结果如下:
这时候可以注意一下,此时当前目录下面会新增出两个文件夹geth和keystore
geth中保存的是区块链的相关数据
keystore中保存的是该链条中的用户信息
此时从Atom中看到的目录结构是这样的:
Step 3:创建自己的私有链条
执行一条最简单的geth命令,来创建自己的私有链条
geth --datadir "./" --nodiscover console 2&&geth.log
geth的参数项目很多,有兴趣的可以打geth –help 来获得详细信息,我们也会在之后的章节中对关键参数项进行说明。
此时的命令行应该是这样的:
Step 4:在自己的私有链条上创建用户
输入命令eth.accounts, 我们会发现返回值为[]
这是因为此时虽然以太坊的私有链已经被创造出来,但还没有任何账户。
输入命令personal.newAccount("xxx"), 该命令将创造一个新的用户,该用户的密码是xxx. 当然用户也可以将xxx 改为123,或者123456,或者任意密码
再次输入命令 eth.accounts, 我们会发现一个新的用户被创建了出来,这就代表我们已经创建了一个账户,重复personal.newAccount() & eth.accounts 我们可以创建若干个账户出来
整个命令截图如下:
Step 5: 输出区块链的Log
在Step 3中,我们执行的代码
geth --datadir "./" --nodiscover console 2&&geth.log
其中的代码 console 2&& geth.log 代表将控制台的一部分输出,输出到文件geth.log上去。
打开另一个终端,找到geth.log的所在目录,执行命令 tail -f geth.log 从而持续的输出以太坊的日志
整个过程如下图所示:
Step 6: 最重要的一步来了,开始挖矿!
在命令行中执行命令 miner.start(), 开始在我们的区块链上进行挖矿
此时Geth.log的输出应该是这样的
一直等到100%。这个以太坊私有链就会正式启动,并持续不断的生成出以太坊来。
1. 挖矿挖到的ether币会默认保在第一个账户中,即eth.acccounts[0]中。
2. 挖矿是执行智能合约的基础。如果停止挖矿的话,不仅以太币会停止生成,所有智能合约的调用也会不起作用。
3. 如果真的要停止挖矿,可以执行命令miner.stop()来停止挖矿
4. 按上面的命令,应该是可以实现以太坊挖矿的。如果不行的话,有可能就是之前有存在的链,此时应该删除之前的数据。在Mac下即删除~/.ethash文件夹和里面的文件即可
Step 7: 最终当挖矿启动的时候的日志是这样的
Step 8: 挖矿启动后,查看主账户的以太币数量
acc0 = eth.accounts[0]
eth.getBalance(acc0)
结果只要不为0,那就说明挖矿成功!
下一章,将讲解geth中的若干概念,以及一些基本命令
发文时比特币标准价格 买价:¥8321.00
卖价:¥8195.00
您需要登录后才可以回复
执行一步失败一步,无语
miner.start()返回值是null是为什么呢?
我也出现了这样的问题,请问您是怎么解决的呢?
你好,我用miner.start()启动并初始化100%之后就报错了,没有正常挖矿,请问是哪里有问题
I:02.196690 vendor/github.com/ethereum/ethash/ethash.go:291] Generating DAG: 100%
I:02.226578 vendor/github.com/ethereum/ethash/ethash.go:276] Done generating DAG for epoch 0, it took 12m4.s
I:41.408799 usb.go:93] handle_events: error: libusb: interrupted [code -10]
以太坊的生产网络顾名思义,也就是产生真正有价值的 的以太币的网络。数字货币交易系统定制开发qq
挖矿是执行智能合约的基础。如果停止挖矿的话,不仅以太币会停止生成,所有智能合约的调用也会不起作用。在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
点击阅读原文
实操:如何在私有区块链上编写、部署以及与以太坊进行交互的智能合约
1月9日 发布,来源:
本文作者以极长的篇幅给出了在私有区块链上编写、部署以及与以太坊进行交互的智能合约的较为完整的代码、相关细节步骤、用户界面等。作者是希望借助他这篇文章,大家可以自行在私有以太坊区块链上编写并部署一个智能合约,以下是译文。
翻译:无阻我飞扬
这里的规则是:如果通读本文,则必须自行在私有以太坊区块链上部署一个智能合约。Github上给出了所有我使用的代码,所以你没有理由不去做。
但是如果不遵守规则,只是想阅读一下而已,希望这有助于提供一个从无到有做出一个区块链应用程序的视角。
最后,你会创建出一个私有以太坊专用区块链,连接两个不同的节点作为peers,编写并编译一个智能合约,有一个允许用户提出问题的Web界面,在区块链上部署问题,然后让用户来回答。
如果感到困惑,遇到错误,或者想说点别的,那就写一篇评论,在上取得或发表意见。
这里是,所以继续并fork它(如果不想复制粘贴所有的代码),如果有想要分享的更新,我会把它放到自述文件中。
私有区块链创建
要创建一个单独的节点,需要以下genesis.json代码,它代表私有区块链上的初始块。
//genesis.json
"alloc": {},
"config": {
"chainID": 72,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
"nonce": "0x0000",
"difficulty": "0x4000",
"mixhash": "0x0000",
"coinbase": "0x0000",
"timestamp": "0x00",
"parentHash": "0x0000",
"extraData": "0x11bbe8db4e347b4e8c937c1ced33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0xffffffff"
如果希望对字段有一个完整的解释,看看这个堆栈溢出的解答。这个案例中的difficulty是很低的,因为不希望在测试网络上等待很长的时间,区块才能被挖掘出来,然后gasLimit 的值高到允许区块中的一个节点可以完成的工作量能够处理每个交易。
去打开一个终端,确保geth(以太坊客户端)以任何适用于你的操作系统的方式进行安装,然后cd(dos命令)到保存genesis.json的文件夹。运行以下命令,将初始化该节点的区块链。
$ geth --datadir "/Users/USERNAME/Library/PrivEth" init genesis.json
-datadir指定区块链所有数据的位置。在Mac操作系统上,默认是 ~/Library/Ethereum目录。由于有多个节点在运行,所以不能让它们共享相同的数据文件夹,因此需要具体指定。Linux和Windows机器具有不同的,所以请查看这些数据一般应该位于何处。
用genesis.json文件运行完初始化命令之后,去检查那个--datadir目录,会看到一堆文件,所以随意四处看看吧。现在没有必要,但是最终还是要去看看。
对于这样一个区块链,需要多个节点。要使区块链成为peers,它们需要拥有相同的创始文件。所以要从同一个目录运行和上面相同的命令,但是这次使用了不同的datadir。
geth --datadir "/Users/USERNAME/Library/PrivEth2" init genesis.json
这里所有的代码,将在同一个目录下工作。代码是一样的,但是使用命令行选项,可以通过命令行参数区分这些进程。
初始化两个节点的链。
当通过一个不同的--datadir运行geth,无论从哪里运行命令,都将运行单独的节点。只要记得每次指定--datadir,那么它就不会回到默认值。另外请注意,我更改了这些datadirs的名称,所以会在屏幕截图中看到不同的名称。
打开控制台
到目前为止,已经做了三件事。1)在选择的工作目录中创建了一个genesis.json 文件,2)为一个节点选择一个目录存储区块链,并初始化第一个区块,3)为另外一个节点选择一个不同的目录存储区块链。很少的代码和一些命令。
下一步能够登录到每个节点的geth控制台。控制台将启动geth进程并运行它,也给了在终端上运行一些web3命令的方法。
geth --datadir "/Users/jackschultz/Library/EthPrivLocal" --networkid 72 --port 30301 --nodiscover console
这里还有更多的选择。
-networkid与genesis.json文件中的类似,在这里所需要做的是确保不使用网络ID 1-4。
-port指定.ipc文件将要用到的端口。这就是使用web3.js库连接数据库的方式,默认端口是30303。所以将它保留在那个区域,但这是第一个节点,所以它的端口是30301。
nodiscover告诉geth最初不要找peers。这一点在这个案例中确实很重要。这是一个私有网络。不希望节点在没有指定的情况下尝试连接到其它节点,不希望这些节点在没有告诉它们的情况下被发现。
在第一个geth节点运行的情况下,在有第二个—datadir的不同终端运行相同的命令,节点在不同的端口上运行。
启动控制台。为每个节点创建初始Coinbase帐户
当用上面的命令运行控制台时,想要创建主coinbase帐户。如果感到好奇,使用密码短语“passphrase”,将来Node应用程序会用到“passphrase”。
& personal.listAccounts
& personal.newAccount()
Passphrase:
Repeat passphrase:
0xdb4b64e320e6c7ca6880c
& personal.listAccounts
[“0xdb4b64e320e6c7ca6880c”]
在另一个节点的控制台中运行相同的命令。
创建新的帐户。
由于这是该节点创建的第一个帐户,因此会看到它也列在其中
& eth.coinbase
0xdb4b64e320e6c7ca6880c
在控制台上抓取的另一条信息
& personal.listWallets
accounts:[{
address:“0xdb4b64e320e6c7ca6880c”,
url:“keystore:///Users/jackschultz/Library/EthPrivLocal/keystore/UTC--T16-21-48.Z--db4b64e320e6c7ca6880c”
status:“locked”,
url:“keystore:///Users/jackschultz/Library/EthPrivLocal/keystore/UTC--T16-21-48.Z--db4b64e320e6c7ca6880c”
在那里会看到更多有关帐户的信息,而不是只有地址。还会看到帐户信息的存储位置,它会在指定的--datadir。所以如果仍然好奇数据是如何存储在文件系统中的,那就去查看一下目录。
以Peers连接节点
有多个节点正在运行,需要以peers连接它们。首先检查我们是否有peers
& admin.peers
好难过。这是我们期望的,在非1-4网络ID和nodiscover的标志上启动控制台。这意味着需要告知每个节点用特定的命令连接到另一个节点。通过分享enode 地址的方式来做。
& admin.nodeInfo.enode
“enode:// 13b835d62b53db466fea481e31cedce63def5eebaf3a0b6fc8a9 @ [:]:30301 discport = 0”
这是geth用来连接到不同节点的enode信息,在这些不同的节点它们能够分享交易和成功挖掘信息。
要使用这个URL连接节点,需要调用addPeer函数。
如果要复制从其中一个节点admin.nodeInfo.enode的返回值,请在另一个节点中运行以下命令。
& admin.addPeer(“enode:// 13b835d62b53db466fea481e31cedce63def5eebaf3a0b6fc8a9 @ [::]:30301?discport = 0”)
这告知一个节点如何到达另一个节点,并请求另一个节点连接起来,它们都将成为彼此的peers。如需检验,请在两个节点上运行admin.peers命令,将看到它们连接在一起。代码如下:
& admin.peers
caps: ["eth/63"],
id: "99bf59fe629dbea3cb3da94be4a6cff625c40da21dfffacddc4faa77cd4fbd5ebfc0d433b9f718a2cf2e9a8",
name: "Geth/v1.7.1-stable-/darwin-amd64/go1.9.1",
network: {
localAddress: "[::1]:30301",
remoteAddress: "[::1]:50042"
protocols: {
difficulty: 935232,
head: "0x8dd2dcbbd5aacc53f87e590a469e5bde3945bee0f6ae",
version: 63
要添加peer,只需要告诉一个节点连接到另一个节点,然后检查另一个节点,就会看到如下输出:
Peers on peers。
检查余额并挖掘
既然节点连接起来了,就不是钱的事了。在开始挖掘之前,检查一下主账户的余额。
& eth.getBalance(eth.coinbase)
再一次如此悲伤。由于没有把这个帐户分配给创始区块,需要开始为这些账户挖矿。
在控制台中,运行miner.start()为这个节点开始挖掘,然后运行miner.stop()可以停止挖掘。在挖掘时,不仅要看账号得到多少以太币,还要观察两个节点之间点对点的交互。
在下面的图片中,会看到检查了两个节点各自的主帐户余额。然后在节点1上开始挖掘,让它运行大约5秒,然后在7个完整区块之后停止挖掘。检查另一边的余额,有35个以太币,在控制台中这个数字代表Wei。在另一个节点上,将会看到它收到了从节点1挖掘的7个区块的信息。
开始挖掘。
使用智能合约需要专门的交易,但在实现这一点之前,要知道如何创建一个交易,将以太币发送到另一个帐户。
在一个节点上,采用coinbase账户并解锁它。
& coinbaseAddress = eth.coinbase
& personal.unlockAccount(coinbaseAddress)
Unlock account 0xc4e5bd0b7e1
Passphrase:
现在从另一个节点的coinbase帐户复制地址,并回到未解锁的帐户节点
& hisAddress = "0xe8ea3aa92ea"
在此之后,sendTransaction命令有点简单。
& eth.sendTransaction({from: eth.coinbase, to: hisAddress, value: })
INFO [12-09|10:29:36] Submitted transaction fullhash=0x7b5f0dee9fde8fcd97dd57 recipient=0xE8Ea3Aa92EA
"0x7b5f0dee9fde8fcd97dd57"
还有一件需要注意的事,而且会很容易混淆的,就是为什么这些数字的值有那么多0。这是因为值是用wei来表示的,所以不必处理可能在不同系统上引起问题的浮点数。这将与gas(一个与计算步骤大致相当的测量法。每笔交易都需要包括一个Gas限制和一个愿意为每个Gas支付的费用;矿工可以选择进行交易和收费)一起发挥作用 ,需要开始指定合同部署和交易。
如果想知道用这个值发送了多少以太币,命令如下:
& web3.fromWei(,'ether')
要使交易发送,并且看到不同余额的差异,需要在节点中启动矿工,然后在挖掘了一个区块后停止,现在检查余额以查看变化。
& miner.start()
...............
& miner.stop()
& web3.eth.getBalance(eth.coinbase)
& web3.eth.getBalance(hisAddress)
接下来看看下面的这张巨幅图片。同样,节点1在左边,节点2在右边。所以首先检查每个节点上各自coinbase账户的余额。在节点1上,复制节点2的地址,发送交易,然后从接收到提交的交易的节点登录,接着开始挖掘。会发现节点8 有txs=1,这意味着它在那个区块挖掘了一笔交易。再多挖几个区块以后,停止挖掘。检查节点1的帐户余额。有12个区块,每个区块奖励5以太币,但后来却付出了wei。
现在,回到节点2,检查其coinbase帐户的余额,余额是0。然后,记得重新启动过节点1的控制台,并没有将两个节点设置为peers。因此,打印节点1的enode,作为一个peer将其添到节点2。在添加peer后,会看到节点2接收到错过的块,包括1个交易。然后再次检查余额,发现它有Wei。
这是如何在本地发送以太币。
到这里,差不多完成了一半的工作!在一个拥有本地运行的私有以太坊区块链的终端上工作,拥有账户的两个节点,彼此是peers,并且可以来回发送交易。
这相当不错,所以可以花一点时间冷静下来,有一个更好的理解。但是在此刻,请继续前进。
在Remix上编写一个合约
继续!随着geth节点的运行,下一步就是签订合约。
当写这样的文章时,需要花很长时间来选择一个简单而有价值的例子。当试图选择一种合约来使用时,情况亦是如此。我决定摆在这里的是人们可以回答是/否或真/假的问题。
下面是Solidity(是以太坊中用于开发智能合约的编程语言,目前开发智能合约用的最多的是Solidity)合约的最终v1代码。在看代码之前,有一些注意事项:
在这个例子中,只使用全局变量来解决问题,是谁问了这个问题,谁回答了这个问题,以及答案的值。Solidity也有可以存储数据的结构,但是本文在讨论部署而不是Solidity,所以不要太深入。
使用 uints来存储是/否的答案,而不是bools。在Solidity中,如果有将地址链接到bool的映射,则默认值为FALSE。对于一个uint,默认值是零。这有了必要的三种状态,在这里可以用一个enum,但正如我所说,尽量保持简单。
answerQuestion方法在逻辑和if语句中都有些复杂。如果想了解如何调整变量,请仔细阅读它。
有一个get函数,返回所有想要在页面上显示合约状态的信息。可以分开来分别返回不同的信息,但是不妨把它们放在一起,而不必多次查询。 -在合约中不仅有其它方式存储这些数据,还有很多其它的方式来编写它!例如,可以列出所有投票为true或false的账户,然后循环查询它们是否已经回答。
pragma solidity ^0.4.0;
contract Questions {
//global variables that aren't in a struct
mapping(address =& uint) //integer where 0 means hasn't answered, 1 means yes, 2 means no
/// __init__
function Questions(string _question) public {
asker = msg.
question = _
//We need a way to validate whether or not they've answered before.
//The default of a mapping is
function answerQuestion (bool _answer) public {
if (answers[msg.sender] == 0 && _answer) { //haven't answered yet
answers[msg.sender] = 1; //they vote true
trues += 1;
else if (answers[msg.sender] == 0 && !_answer) {
answers[msg.sender] = 2; //falsity
falses += 1;
else if (answers[msg.sender] == 2 && _answer) { // false switching to true
answers[msg.sender] = 1; //true
trues += 1;
falses -= 1;
else if (answers[msg.sender] == 1 && !_answer) { // true switching to false
answers[msg.sender] = 2; //falsity
trues -= 1;
falses += 1;
function getQuestion() public constant returns (string, uint, uint, uint) {
return (question, trues, falses, answers[msg.sender]);
把这个合约保存在contracts/Question.sol中,而不是在本地进行编译,使用来处理大量的错误和代码警告,以及编译所需的信息。
要查看编译信息,在右上角的“编译”选项卡上单击详细信息按钮,就会看到一堆信息弹出。要寻找的数据是byteCode和ABI。右下方正是要模仿的web3的部署信息!但是,不是从一个单一的行上输入巨大的字符串,而是要从一个json文件中导入信息。必须把数据分开。
//childContractv1.json
"abi": [{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"answers","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getQuestion","outputs":[{"name":"","type":"string"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_answer","type":"bool"}],"name":"answerQuestion","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_question","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}],
"byteCode": "0x0affffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb601f60ff5bfbfdc565b5b5b12b0f565b65b3dfc0463ffffffff8e063eff38f5bbb803573fffffffffffffffffffffffffffffffffffffffff35bb565b5b0efa080fd5bb005bb565bffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff............................565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffffb5b5b5baadefebf8fa91b1cdffcabd4ddd2ff0029"
继续直接复制这个文件,到Remix上并与Remxi的编译器一起工作。值得一提的是byteCode,需要确保字符串以“0x”开始。当从Remix复制字节码字段时,只能得到数字。
NodeJS时间
上面每次说到节点,意思是geth / blockchain节点。在这里,将再次看到“node”这个词,但是当看到大写字母N时,它的意思是NodeJS。
已经将v1合约编译并存储在一个文件中。现在需要运行一个Node(这个Node首字母大写了,所以它代表NoteJS)实例。将有四个端点:
GET’/’将会有一个表单提出一个新的问题,
POST’/ questions / new’在区块链上部署新问题合约,
GET’/ questions?address = 0xXXXX …’将依据当前的答案显示问题以及一个发送或更新答案的表单, -POST’/ questions?address = 0xXXXX …’处理应答。
前言,在进入区块链之前,从来没用使用过Node,所以有一些语法和实践可能会在这里无效。对于代码,会通过与区块链交互的三个端点,首先是部署新问题的post请求。这些代码需要连接到本地运行的geth。
const Web3 = require('web3');
const net = require('net');
const compiledContract = require('./contracts/contractv1');
web3IPC = '/Users/jackschultz/Library/PrivEth/geth.ipc';
let web3 = new Web3(web3IPC, net);
const byteCode = compiledContract.byteC
const QuestionContract = new web3.eth.Contract(compiledContract.abi);
web3.eth.getCoinbase(function(err, cba) {
coinbaseAddress =
console.log(coinbaseAddress);
const coinbasePassphrase = 'passphrase';
app.post('/', (req, res) =& {
const question = req.body.
web3.eth.personal.unlockAccount(coinbaseAddress, coinbasePassphrase, function(err, uares) {
QuestionContract.deploy({data: byteCode, arguments:
}).send({from: coinbaseAddress, gas: 2000000})
.on('receipt', function (receipt) {
console.log("Contract Address: " + receipt.contractAddress);
res.redirect('/questions?address=' + receipt.contractAddress);
当到达端点时,从主体获取请求后的第一步是解锁正在部署的帐户。这是必要的,不模仿别人。一旦得到回调,将部署合约,其中交易的数据是整个的字节码,然后将问题字符串传递给合约中的init函数。指定从coinbase地址发送它,并说明要投入2000000wei(如果想知道它到底有多小,那就是0. 以太币)。
但现在唯一感兴趣的是“收据”,合约被挖掘以后,它的地址在哪里。就用户界面而言,这样写的方式是在重定向到问题的页面之前,页面会挂起,等待合约被挖掘。对于广泛使用的DAPP(Decentralized App,去中心化的应用程序)来说,这可能不是一个好主意,因为公共以太坊挖掘区块平均约为14.5秒。但是这里的私有区块链上,把难度设置的如此之低,以至于区块很快被挖掘完,所以这不是问题。
现在既然有一个问题存在,就想继续讨论它!使用web3.utils.isAddress函数来验证地址不仅是一个有效的十六进制字符串,而且还验证校验和是有效的,确保它是一个存在的地址。
然后getQuestion 方法返回一个结果,这是一个返回值的字典。在本文的例子中,这是一个问题,true的数量,false的数量,以及运行节点的人是否回答了这个问题。
app.get('/questions', function(req, res) {
const contractAddress = req.query.
if (web3.utils.isAddress(contractAddress)) {
QuestionContract.options.address = contractA
const info = QuestionContract.methods.getQuestion().call(function(err, gqres) {
//using number strings to get the data from the method
const question = gqres['0'];
const trues = gqres['1'];
const falses = gqres['2'];
const currentAnswerInt = parseInt(gqres['3'], 10);
data = {contractAddress: contractAddress, question: question, currentAnswerInt: currentAnswerInt, trues: trues, falses: falses};
res.render('question', data);
res.status(404).send("No question with that address.");
当发布这个问题url时,经过大部分相同的过程验证输入,验证地址,然后用所需参数调用answerQuestion方法。随着问题创建函数的出现,将让浏览器挂起,直到有更新交易的区块被挖掘出来。
app.post('/questions', function(req, res) {
const contractAddress = req.query.
const answerValue = req.body.answer == 'true' ? true :
if (web3.utils.isAddress(contractAddress)) {
web3.eth.personal.unlockAccount(coinbaseAddress, coinbasePassphrase, function(err, uares) {
QuestionContract.options.address = contractA
QuestionContract.methods.answerQuestion(answerValue).send({from: coinbaseAddress, gas: 2000000})
.on('receipt', function (receipt) {
console.log(`Question with address ${contractAddress} updated.`);
res.redirect('/questions?address=' + contractAddress);
至于HTML,不打算费心把它贴在这里,因为它很简单。我不喜欢使用CSS模板,因为像这样在后台提交并不重要。当谈论到运行代码时,会看到以下基本界面的屏幕截图。
现在所有的代码都在那里。控制台上有四个选项卡打开。两个正在运行geth
geth --datadir /Users/jackschultz/Library/PrivEth --networkid 40 --port 30301 --nodiscover console
geth --datadir /Users/jackschultz/Library/PrivEth2 --networkid 40 --port 30302 --nodiscover console
另外两个正在运行Node应用程序,连接到单独的geth过程,并运行在不同的本地主机端口上。添加了,将它们命名为主文件和辅助文件,指向ipc和该节点应当运行的端口。
NODE_ENV=primary node app.js
NODE_ENV=secondary node app.js
在这里放一些图片,让阅读的人可以更多地了解我在屏幕上看到的内容。在此基础上,打开浏览器并开始交互。首先是进入主页,可以问一个问题。
他们会吗??
然后当点击提交按钮时,会看到Node应用程序的日志记录,在geth控制台中,将启动矿工,然后在这个交易完成后停止它。
是时候回答问题了。
回答的话,要提交表单,然后开始和停止挖矿。当自己做这件事的时候,一件有趣的事情就是在提交答案之前先启动矿工,这样就可以了解在创始块中定义的这个小难度级别的挖掘速度。
检查下面的终端。在顶级Node终端中,将看到有关验证地址的一些日志记录,然后当重定向到同一页面但具有更新信息时记录。在geth控制台中,可以看到交易何时提交,以及这笔交易是在哪个区块进行的。
显然他们会。
现在从主节点回答了这个问题,接着看看第二个节点。
在图片的右侧,会看到前两个终端显示Node和geth交互,然后底部是主要的geth,可以看到它接收到一个交易的区块,因为这两个geth节点是peers。在端口4002上的节点回答问题后,重新加载了端口4001上的页面,可以看到下图的结果。
当然会的。
为了证明可以切换回false,把端口4002的答案改成了false(这是错误的,因为雄鹿队肯定会打入季后赛),然后可以看到控制台记录了所经历的信息。
截图后,改回答案为true。
如果已经看到了这里,并且让自己的代码运行起来了,恭喜。 像大多数帖子一样,这比我最初想象的要长得多。这样做的目的是完成并解释智能合约的所有步骤,而不是只给出中间的某个地方。
如上所述,如果有任何反馈,在上取得或发表意见。
我要该,理由是:
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)

我要回帖

更多关于 私有区块链环境 的文章

 

随机推荐