建议和反馈

请填写你的反馈内容

x
  • 【一】QTUM智能合约开发指南 | 运行QTUM - Docker容器

    QTUM智能合约开发指南QTUM是一个基于比特币UTXO模型的去中心化区块链项目,同时也支持以太坊的智能合约虚拟机。QTUM通过创新性地引入账户抽象层(Account Abstraction Layer,AAL)使得比特币网络和以太坊网络可以兼容。想获取QTUM更多的信息或者加入我们的社区,请访问:https://qtum.org该书的网址为:https://book.qtum.orgQTUM Docker Container(Docker容器)本书中,我们创建一个docker image(docker镜像)来确保运行环境一致,这样就更容易按照下面的例子进行操作。 docker容器包括qtumd和本书其余部分中将用到的所有工具。下载最新的容器镜像:docker pull hayeah/qtumportal:latest运行regtest模式对于开发和测试,运行一个本地区块链是最方便的,因为在自己的电脑上处理生成的交易是很便宜的。 开发者可以很容易地使用qtumd内嵌的regtest模式 (regression test mode,回归测试模式)运行一个本地的区块链。regtest和以太坊的testrpc类似,但在以下几个方面有所不同:区块链状态存储在磁盘上,并且在qtumd重新启动时仍然存在。区块不是立刻被挖出的,而是在一个半规律的时间间隔内。需要手动生成600个区块。默认情况下,hayeah/qtumportaldocker镜像启动qtumd的regtest模式:docker run -it --rm \   --name myapp \   -v `pwd`:/dapp \   -p 9899:9899 \   -p 9888:9888 \   -p 3889:3889 \   hayeah/qtumportal--name 容器的名称,可以将它改成任何名称。-it 为容器分配一个终端设备。--rm 退出后立刻删除容器。-v 把当前目录映射为容器中的/dapp目录。-p 显示容器端口,以便主机操作系统访问。应该看到如下输出:02:46:17 portal | Starting portal on port 5001 02:46:17  qtumd | Starting qtumd on port 5000 02:46:17 portal | time="2017-12-13T02:46:17Z" level=info msg="DApp service listening 0.0.0.0:9888" 02:46:17 portal | time="2017-12-13T02:46:17Z" level=info msg="Auth service listening 0.0.0.0:9899" 02:46:17  qtumd | 2017-12-13 02:46:17 02:46:17  qtumd | 2017-12-13 02:46:17 Qtum version v0.14.10.0-101922f-dirty 02:46:17  qtumd | 2017-12-13 02:46:17 InitParameterInteraction: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1 02:46:17  qtumd | 2017-12-13 02:46:17 Validating signatures for all blocks. 02:46:17  qtumd | 2017-12-13 02:46:17 02:46:17  qtumd | 2017-12-13 02:46:17 Default data directory /root/.qtum 02:46:17  qtumd | 2017-12-13 02:46:17 Using data directory /dapp/.qtum/regtest ... 02:46:22  qtumd | 2017-12-13 02:46:22 ERROR: Read: Failed to open file /dapp/.qtum/regtest/banlist.dat 02:46:22  qtumd | 2017-12-13 02:46:22 Invalid or missing banlist.dat; recreating 02:46:22  qtumd | 2017-12-13 02:46:22 init message: Starting network threads... 02:46:22  qtumd | 2017-12-13 02:46:22 net thread start 02:46:22  qtumd | 2017-12-13 02:46:22 addcon thread start 02:46:22  qtumd | 2017-12-13 02:46:22 init message: Done loading 02:46:22  qtumd | 2017-12-13 02:46:22 opencon thread start 02:46:22  qtumd | 2017-12-13 02:46:22 msghand thread start 02:46:22  qtumd | 2017-12-13 02:46:22 dnsseed thread start 02:46:22  qtumd | 2017-12-13 02:46:22 Loading addresses from DNS seeds (could take a while) 02:46:22  qtumd | 2017-12-13 02:46:22 0 addresses found from DNS seeds 02:46:22  qtumd | 2017-12-13 02:46:22 dnsseed thread exit可在终端中按ctrl-c 来终止容器,并且能够看到一些更整洁的日志:02:48:06  qtumd | 2017-12-13 02:48:06 tor: Thread interrupt 02:48:06  qtumd | 2017-12-13 02:48:06 torcontrol thread exit 02:48:06  qtumd | 2017-12-13 02:48:06 addcon thread exit 02:48:06  qtumd | 2017-12-13 02:48:06 opencon thread exit 02:48:06  qtumd | 2017-12-13 02:48:06 scheduler thread interrupt 02:48:06  qtumd | 2017-12-13 02:48:06 Shutdown: In progress... 02:48:06  qtumd | 2017-12-13 02:48:06 msghand thread exit 02:48:06  qtumd | 2017-12-13 02:48:06 net thread exit 02:48:06  qtumd | 2017-12-13 02:48:06 Dumped mempool: 0.001657s to copy, 0.00729s to dump 02:48:06  qtumd | 2017-12-13 02:48:06 ...  02:48:06.292|  Closing state DB 02:48:06  qtumd | 2017-12-13 02:48:06 ...  02:48:06.306|  Closing state DB 02:48:06  qtumd | 2017-12-13 02:48:06 Shutdown: done 02:48:06  qtumd | Terminating qtumd你将看到regtest的区块链数据库已经创建在本地project目录的.qtum/regtest路径下:ls .qtum/regtest banlist.dat       chainstate        debug.log         mempool.dat       stateQtum         wallet.dat blocks            db.log            fee_estimates.dat peers.dat         vm.log重启容器, qtumd应该能够复用保存在.qtum的区块链数据库。docker run -it --rm \   --name myapp \   -v `pwd`:/dapp \   -p 9899:9899 \   -p 9888:9888 \   -p 3889:3889 \   hayeah/qtumportal运行测试网络开发者可以通过设置容器内QTUM_NETWORK的环境变量来运行测试网路,例如:docker run -it --rm \   --name myapp \   -e "QTUM_NETWORK=testnet" \   -v `pwd`:/dapp \   -p 9899:9899 \   -p 9888:9888 \   -p 3889:3889 \   -p 13888:13888 \   hayeah/qtumportal使用Shell访问容器验证容器是否正在运行:docker psCONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                                                      NAMES 72d7b2c22f97        hayeah/qtumportal   "/bin/sh -c 'mkdir..."   About a minute ago   Up About a minute   0.0.0.0:9888->9888/tcp, 0.0.0.0:9899->9899/tcp, 0.0.0.0:13889->13889/tcp   myapp容器的名称是myapp。可以获得shell访问:docker exec -it myapp sh容器内的/dapp目录应该和你的project目录一样。在容器内,可以使用qcli命令和qtumd交互。获取一些区块链状态的基本信息,可以使用如下命令:qcli getinfo {   "version": 141000,   "protocolversion": 70016,   "walletversion": 130000,   "balance": 0.00000000,   "stake": 0.00000000,   "blocks": 0,   "timeoffset": 0,   "connections": 0,   "proxy": "",   "difficulty": {     "proof-of-work": 4.656542373906925e-10,     "proof-of-stake": 4.656542373906925e-10   },   "testnet": false,   "moneysupply": 0,   "keypoololdest": 1513133181,   "keypoolsize": 100,   "paytxfee": 0.00000000,   "relayfee": 0.00400000,   "errors": "" }生成新区块链初始时是空的。正如我们在getinfo中看到的,目前还没有区块:"blocks": 0并且初始的钱包余额也是0:qcli getbalance 0.00000000在regtest模式下,允许挖掘新的区块用于测试。这在以下两方面是很有用的:能够产生足够的余额来支付交易费用。能快速确认交易而不需要等一个新的区块被挖掘出来。生成600个区块的方法如下:qcli generate 600[   // more ...   "43e9c190679a4d040d07c6d0d5d34c1d49f7b6b6539ceb87eea76af3ef39eed5",   "7d5b6a0e5e76cf18e35ac18d4534155a0fd96201feaefc720118452dd50bcd5b",   "70013fa6e01ad527e1f71033ebf59c5233877fcd0fd8233ea032ddaface3cbbc",   "6c73fe21f7c7874b550e190dcc69320c13a96f188bfb89ab858bc42adc0a1398",   "5b48289b22fbf073f6a345d97968c3b8ee44381e8e10e6f940d31b7355684968",   "4f9444d8bd3ece4f6839d7bcfc7f964e95187e2868128681b7bc4cb42d719b41" ]此时,钱包的余额不再是0:qcli getbalance 2000000.00000000并且区块的数量大约是600:qcli getinfo "blocks": 603,注意:QTUM的POS挖矿奖励是不能立即花费的,直到500个区块之后才会“成熟”并能被使用。通过产生600个区块,可以获得100个“成熟”的区块奖励,每个区块奖励都是2万个QTUM。总结在本章中,我们在docker容器中运行了qtumd:docker run -it --rm \   --name myapp \   -v `pwd`:/dapp \   -p 9899:9899 \   -p 9888:9888 \   -p 3889:3889 \   hayeah/qtumportalshell进入容器中:docker exec -it myapp sh一旦进入容器中,使用qcli命令和qtumd交互,例如:qcli getinfo获取可用的qcli命令和参数列表,可以使用:qcli help... more listsinceblock ( "blockhash" target_confirmations include_watchonly) listtransactions ( "account" count skip include_watchonly) listunspent ( minconf maxconf  ["addresses",...] [include_unsafe] ) lockunspent unlock ([{"txid":"txid","vout":n},...]) move "fromaccount" "toaccount" amount ( minconf "comment" ) removeprunedfunds "txid" reservebalance [<reserve> [amount]] sendfrom "fromaccount" "toaddress" amount ( minconf "comment" "comment_to" ) sendmany "fromaccount" {"address":amount,...} ( minconf "comment" ["address",...] ) sendmanywithdupes "fromaccount" {"address":amount,...} ( minconf "comment" ["address",...] ) sendtoaddress "address" amount ( "comment" "comment_to" subtractfeefromamount ) sendtocontract "contractaddress" "data" (amount gaslimit gasprice senderaddress broadcast) setaccount "address" "account" settxfee amount signmessage "address" "message"

    Qtum量子链

    如何成为加VIP用户?

    VIP用户是链客特邀的行业权威和技术大咖,您想成为VIP用户?查看行情>

    如何成为加V用户?

    提升链客指数,即可成为加V用户,等级越高享受权益特权越多查看行情>

    如何成为皇冠用户?

    认证成为讲师,即可成为加冠用户,加冠用户享受诸多权益特权查看行情>

    · 2019-06-26
    0阅读 · 0赞赏 · 0问答
  • 公有链有未来还是联盟链有未来

    > 在我们讨论区块链时,分类是不可避免的一件事情。想必大家都听说过「公有链、联盟链、私有链、许可链、无需许可链」这些词汇,虽然我们已经耳熟能详,然而这些名词并没有公认的定义。我们在讨论中只能各凭自己的理解,用这些名词指代大致上相同实际上有些区别的概念,由此造成了上面那样的沟通困难。本文将对这些名词,从最基本的纬度进行分析。在我们讨论区块链时,分类是不可避免的一件事情。想必大家都听说过「公有链、联盟链、私有链、许可链、无需许可链」这些词汇,虽然我们已经耳熟能详,然而这些名词并没有公认的定义。我们在讨论中只能各凭自己的理解,用这些名词指代大致上相同实际上有些区别的概念,由此造成了上面那样的沟通困难。本文将对这些名词,从最基本的纬度进行分析。 秘猿科技区块链小课堂第 5 期 # 维度 1:许可链/无需许可链 ## 无需许可链(permissionless blockchain) 网络参与者可以自由的加入和退出,也即加入或退出网络的成本接近于零。在讨论中听到的“公链”、“公有链”或者“基础链”的时候,我一般会认为是在说无需许可链。 这一类型的区块链包括 Bitcoin/Litecoin/Peercoin/Monero/ZCash/Ethereum 等等。Bitcoin 是无需许可链的开山鼻祖,通过 PoW 巧妙的实现了世界上第一个无需许可的分布式系统,2015 年之前的区块链项目基本上属于这一类。Nervos CKB 是无需许可链,第一阶段使用 PoW 共识。 无需许可链的去中心化程度最高,其发展也高度依赖社区自治,是最有潜力成为全球基础设施的区块链类型。 ## 许可链(permissioned blockchain) 网络参与者需要获得某种形式的许可才可以加入或退出,加入或退出网络的成本大于零。“许可链”在讨论中常常与“联盟链”混用,后面我们会看到这两者的区别。 许可链的思潮在 2014 年兴起,彼时金融机构已经发现了数字货币、智能合约和区块链这片新大陆,并开始思考如何将区块链技术引入自己的业务。对记名资产的登记和交易需求,以及金融业务中 KYC/AML 的需要,让人们开始认识到身份的必要性,以及由此带来的重构区块链的可能1。身份的存在可以很自然的解决让无需许可链头疼的女巫攻击问题,因此也就可以避免 PoW 而使用传统BFT 共识,可以获得更低的能耗和更好的性能。比较早期的公司如 Eris Industries(现改名 Monax)在 2014 年成立,是许可链的先驱。R3 也是在 2014 年成立,虽然 Corda 自称为分布式账本而不是许可链(也确实不仅仅是链,而是一个没有区块、由交易编织成的网络),但它很明显是许可链思潮下的产物。Hyperledger Fabric 和我们自己设计开发的 CITA 都是许可链。 许可链一般由行业联盟或是科技公司设计、实现和推动,具有接近中心化方案的性能,注重金融和企业场景。 ## 细化 如果将网络参与者分为出块节点、全节点和用户(通过钱包访问全节点使用区块链提供的服务)[3],我们可以进一步细化无需许可链和许可链的分类。 ![](https://www.liankexing.com/Public/Uploads/2019-06-26/5d12e74c46c02.png) 我将看起来没有实用价值的组合标记为 Nonsense,不做讨论。 ###用户许可链 在用户许可链中,节点加入、退出、参与共识都不需要许可,但是用户需要获得许可才能使用区块链提供的服务。虽然目前还没有看到用户许可链的实例,但我认为用户许可链是一个非常有意思,值得探索的方向。如果把节点属于网络层,构成了区块链的基础;用户空间存在于节点共同维护的账本/共同知识库之中,是区块链架构中的上层。无需许可的基础层和需要许可的上层是一个很和谐的组合:基础层无需许可,无论什么样的节点都可以参与,网络性质中立,保持了无需许可链的全球基础设施属性;上层需要许可,用户具有某种形式的身份,更加适合需要身份的各类商业和金融场景 ![](https://www.liankexing.com/Public/Uploads/2019-06-26/5d12e75caeeba.png) 用户许可链需要解决的难题也不少:如何实现一个去中心化的身份认证服务?如何在基础层对这个身份协议提供支持?能够识别身份之后,基础层需要根据一定的规则,选择是否为用户提供服务。谁来制订这些规则?如何制订这样的规则?如何保持规则的中立性? ###出块许可链 出块许可链只要求出块节点获得许可。由于全节点可以自由加入,区块链历史和当前状态都不会被出块节点垄断,全节点可以验证并决定是否接受新区块,整个系统依然是透明可验证的,其可靠性(原谅我使用一个模糊的“可靠性”来指代包含可用性、安全性等等在内各种性质,下同)比中心化系统高,比用户许可链/无需许可链低。如果获得许可的出块节点数量不大,系统性能也会非常不错。 值得指出的是,如果我们将“许可”的定义放宽,出块许可链将包含我们常称为“公有链”的一些项目 —— 基于代币抵押或是代币投票的 PoS,本质上是以代币作为一种许可,限制出块节点数量,达到降低共识过程的消息复杂度以提升系统性能的目标。这样一类 PoS 区块链所展现出来的性质,与出块许可链更接近,与无需许可链更遥远。出块许可链与完全许可链之间的主要区别在于全节点和用户是否需要许可,与无需许可链之间的主要区别在于出块节点集合大小是固定还是动态。 ###节点许可链 节点许可链的出块节点和全节点都需要许可,此时只有拥有许可的节点才能复制和验证区块链数据,用户无法获得账本/共同知识库的独立复本,也无法独立进行验证。这样的系统其可靠性弱于出块许可链,比中心化系统略高,性能与出块许可链接近。由于数据只会在小范围内复制,数据隐私性更好。 根据不同的部署,秘猿科技高性能区块链内核 CITA,既可以是出块许可链,也可以是节点许可链。 #维度 2:公有链/联盟链/私有链 让我们换一个维度,按照区块链的服务对象来分: 公有链(public blockchain):为公众提供服务的区块链。 联盟链(consortium blockchain):存在一个区块链之外的实体联盟,只对联盟内成员提供服务的区块链。 私有链(private blockchain):存在一个区块链之外的实体,只对实体内成员提供服务的区块链。 「公有链」从 public blockchain 翻译而来,而 public 直译应为「公众、公共」。之所以会翻译成「公有链」,我想大概是由于早期的 public blockchain都有内在的代币机制,使用者即代币持有者,因此也无不妥。但按照今天的眼光看,public blockchain 理解为「公共链」更为合适,「公共链」无差别的对所有公众提供服务,但公众不一定是「公共链」的所有者。我在讨论中还是沿用「公有链」这个词,但我用它指代的其实是「公众链」。 联盟链/私有链在具体实施上有不同的许可链选项:可以是节点许可链、出块许可链或者完全许可链,由此也会有相应的优缺点,在此不再重复。这些不同选项的共同之处是,出块节点都是需要许可的,共识范围有限,牺牲了可靠性换来了更好的性能和隐私。未来联盟链/私有链如果能够以无需许可链作为信任基础,其可靠性和信用也可以提高到与无需许可链接近的程度,实际上会成为无需许可链扩容的助力,这是 Nervos CKB 团队、 Cryptape Research 在探索的方向。如果在跨链协议的帮助,联盟链/私有链之间可以低成本的进行互操作,联盟链/私有链上资产的流动性也将提高到与无需许可链上的资产流动性接近的程度,这是 Cryptape CITA 团队在探索的方向。 ![](https://www.liankexing.com/Public/Uploads/2019-06-26/5d12e7849db2f.png) # 公有许可链(public permissioned blockchain) 考虑维度 1 和维度 2 之间的关系,很容易发现联盟链和私有链都隐含了对用户以及节点的身份限制,因此必然是许可链。有意思的问题是:公有链一定是无需许可链吗? 按照上文对公有链的定义,对公众提供服务并不隐含对用户身份的限制。公有链可以对匿名的公众提供服务,也可以不加选择的对有身份的公众提供服务。公有链中的节点是否需要许可,并不影响一条区块链是否对公众提供服务。因此在我的观念中,一条区块链可以同时是公有链和许可链,这两者之间没有矛盾。我把既是公有链又是许可链的区块链称为公有许可链[4]。 我们日常谈到公有链时往往想的是无需许可链,但是实际上不少公有链更接近公有许可链的范畴,最典型的例子是 Ripple。公有许可链可能的实现形式很多,前面讨论过的许可链、出块许可链、节点许可链、用户许可链都可以是公有许可链。由于身份的存在,公有许可链既有许可链的优点,其适用的场景又与无需许可链互为补充,相信将在未来的加密经济生态中占有重要的位置。 #Summary 联盟链、私有链、许可链常被批评的一点是缺乏内生的经济激励设计,因此“根本不是区块链”。这个观点我们并不赞同。一来经济激励设计和服务对象范围、是否需要许可之间并不存在什么矛盾,我们只是现在还没有看到有内在经济激励的样本;二来具有内生的经济激励是否是成为区块链的必要条件依然是一个值得探讨的问题。 最后回答文章开头的问题:未来将有许多种形态的区块链以及非区块链共存。它们将相互协作,相互促进,相互保障,共同编织一个高效可靠的数字经济网络。

    秘猿科技

    如何成为加VIP用户?

    VIP用户是链客特邀的行业权威和技术大咖,您想成为VIP用户?查看行情>

    如何成为加V用户?

    提升链客指数,即可成为加V用户,等级越高享受权益特权越多查看行情>

    如何成为皇冠用户?

    认证成为讲师,即可成为加冠用户,加冠用户享受诸多权益特权查看行情>

    · 2019-06-26
    89阅读 · 0赞赏 · 0问答
  • CR双周报|2019-06-17

    一 引言*作者 Jeremy G.欢迎查阅CR双周报!本期见证了我们CR生态的特别时刻,DPoS于6月17日正式开启。我们要发布一大波的更新,总结如下:海星超级节点 Starfish Supernode 在他们的官网 elanodes.com 上添加了简明的节点收益计算功能。亦来云基金会就超级节点设置发布了特别指导。亦来云基金会发布了更新版的主网开发路线图供全社区查阅。亦来云开发者体验团队(Elastos DX team)正在全力改进CR。他们的亦来云学院网站及服务将很快上线。来自亦来云开发者体验团队的Jimmy Lipham发布了一个新的视频,包含了很多令人兴奋的信息更新。生态合作伙伴DMA, 发布了新的技术更新,同时也公布了亦来云上有史以来的第一个电商商铺的特别新闻。亦来云基金会的Clarence在中国就音乐产业进行了建设性对话。亦来云基金会成员韩锋就一些对他与MIT关系的FUD(恐惧、不确定和怀疑)进行了澄清。大象钱包实施了多重签名。CR 新闻媒体团队的Famous Amos为亦来云Runtime制作了一个分析视频。*特别鸣谢Elate.ch,泰国超级节点,野草莓超级节点,Ela森林超级节点,韩锋以及休斯顿超级节点成为CR 超级节点的第一批赞助者!请记得访问我们的CR新闻网,并查阅我们的赞助页面。我们也添加了CR观点的标签,用于所有社区成员阅读和贡献内容。如果有任何社区成员有相关的信息要贡献给CR,请使用我们网站上的新闻提交表格上传。亦来云基金会正式宣布完成DPoS共识实施时间表中的第4和第5阶段。这包括最新更新的完全支持完全集成DPoS共识的代码。第5阶段于UTC时间6月17日中午完成。完整的DPoS共识在区块高度402,680时开始运行。亦来云基金会提供了有关如何设置超级节点的完整文档。(https://news.elastos.org/supernode-setup-automation-script/) 这包括技术要求、安装以及如何运行节点。如需进一步的支持或有其它问题,请联系support@elastos.org 。EF还发布了有关主网路线图的全面更新。(https://news.elastos.org/updated-main-net-development-roadmap/) 这是与社区共享的更大新闻之一。 CR 细纹团队已完成了对该更新的完整总结。请阅读以下有关新主网路图的所有细节。亦来云开发者体验(DX)团队已开始向社区推广他们的服务。 亦来云学院将成为潜在开发者的学习舞台。DX团队的顾问Jimmy Lipham最近刚刚发布了关于DX团队进展的视频更新以及他在亦来云平台上构建的自己的项目情况。有关Jimmy更多详细信息总结,请向下继续阅读!elanodes.com的创建者Starfish Node在其网站上添加了一项新功能。访问elanodes.com/calculator,即可了解您大约可以获得多少奖励。您可以查阅到ELA的价格、选民奖励百分比、超级节点排名,超级节点占总投票百分比,以及您的ELA投票权和选民投票率。生态合作伙伴DPMA将在亦来云商开第一家电子商务商品(https://medium.com/@elastosdma/introducing-the-first-decentralised-e-commerce-store-on-elastos-dma-2810b96fc881?source=friends_link&sk=6fbd5b4bba57a9cc9b90095a7af0e304).第一个商家将是由StarryMedia团队运营的T恤和服装店。 DMA希望将来有更多值得信赖的商家加入该商店。 Android版本现已完成,团队计划很快创建iOS版本。DMA也在运行自己的超级节点,并将向选民分发75%的奖励。该团队推出了其ETH侧链,Uptick dApp beta版本以及新的亦来云权限管理平台项目相关的技术更新。来自亦来云基金会的Clarence Liu 在中国就音乐行业展开了建设性的讨论。有些传闻亦来云可能与Ditto Music合作。 Ditto Music是艺术家的一站式商店,用于向全世界推销、推广和分发他们的音乐,同时只收取普通音乐唱片公司的一小部分佣金。我们将密切留意这一潜在伙伴关系的最新消息!大象钱包已经提供了多重签名功能,还有几个更新已经经过了测试。CR新闻媒体也有很多重要的更新。活跃的贡献者Amos发布了一个具有启发意义的关于亦来云Runtime的视频。https://www.youtube.com/watch?v=Pv7UKimtlZY&t=21s.  除了得到了韩锋的大力赞助之外,CR 新闻超级节点还获得了另外五个超级节点的赞助。这些节点中的每一个都被赋予了“黄金之星”以标记其积极主动性。非常感谢Elate.ch,泰国 SN,休斯顿超级节点,野草莓超级节点和ELA 森林超级节点,感谢他们对团队的慷慨支持。 野草莓超级节点和ELA 森林超级节点都将贡献其奖励的5%以上给CR 新闻媒体团队,这使他们获得了CR“堡垒Keeps”的声望。这意味着除了其他一些好处之外,我们还将在我们的网站上展示关于这些内容的文章。*引言作者:Jeremy G.二 项目更新Cyber Republic网站:主项目Repo: https://github.com/cyber-republic/CyberRepublicGit活动与更新:请参阅下文所述的时间表:https//blog.cyberrepublic.org/2018/12/27/important-cyber-republic-announcement三  术语释义像亦来云和 Cyber Republic 这样的大型项目有很多术语,我们决定建立一个不断增加的术语表,这些术语可以帮助不熟悉技术的人更好地理解这些技术的含义,以及它们将会带来的影响。本周我们将聚焦Daemon守护进程。术语:Daemon守护进程在多任务计算机操作系统中,守护进程(Daemon /diːmən/或/deɪmən/)是作为后台进程运行的计算机程序,而不是由交互式用户直接控制……在Unix环境中,父进程守护进程通常是(但不总是)init进程。守护进程通常由一个进程分支创建子进程然后立即退出,从而导致init采用子进程,或者由init进程直接启动守护进程。此外,通过分叉和退出启动的守护程序通常必须执行其他操作,例如将进程与任何控制终端(tty)分离。这些过程通常在各种便利例程中实现,例如 守护进程(3) Unix中的。系统通常在启动时启动守护进程,它将通过执行某些任务来响应网络请求,硬件活动或其他程序。诸如cron之类的守护进程也可以在预定时间执行定义的任务。

    亦来云

    如何成为加VIP用户?

    VIP用户是链客特邀的行业权威和技术大咖,您想成为VIP用户?查看行情>

    如何成为加V用户?

    提升链客指数,即可成为加V用户,等级越高享受权益特权越多查看行情>

    如何成为皇冠用户?

    认证成为讲师,即可成为加冠用户,加冠用户享受诸多权益特权查看行情>

    · 2019-06-26
    77阅读 · 0赞赏 · 0问答
  • GMQ钱包:GMQ钱包让人们享受到更加便捷的生活方式

    区块链钱包由于满足了用户管理数字资产的刚需,所以用户量可以做到很高,今天中国币圈投资者基本上没有人不知道区块链钱包。随着去中心化交易所技术的不断改善和提高,我们有理由相信钱包内置去中心化交易平台会是一个大趋势,一旦人们的交易需求被满足,那么人们极有可能会抛弃中心化交易所。而除了交易需求,未来更大的想象空间应该来自DAPP的大爆发,互联网以及随后的移动互联网最为火热的阶段都是大量应用层出不穷的时候,移动支付钱包在连接各项应用的同时,也让人们享受到了更加便捷的生活方式。我们有理由相信随着区块链基础设施的不断完善,未来基于区块链支付钱包将成为众多DAPP的流量入口。GMQ钱包APP诞生至今,注册用户量节节攀升,GMQ钱包采用简洁直观的UI界面,设有丰富人性化的功能,同时兼容多种数字资产,安全便捷,一键添加,轻松管理数字资产,致力于成为您专属的保险柜,为您带来最安全的数字资产管理方案。GMQ钱包APP可以方便用户储存多种虚拟货币,在储存过程中GMQ钱包APP为最大限度的保护用户货币安全,将实现私钥物理永不触网,中间用户行为分析和审计系统将对签名交易进行实时审计,保证每笔转出交易真实有效,并且在使用过程中,只要不忘记密码,你的账户就会一直存在,数字货币也会一直储存在其中。从一定意义上讲,钱包就是进入区块链世界的入口,能够为用户提供安全可靠、便捷高效的数字资产管理工具GMQ钱包APP正在借助钱包这个区块链世界的入口,积极打造并维护区块链健康生态的发展。

    区块链社区

    如何成为加VIP用户?

    VIP用户是链客特邀的行业权威和技术大咖,您想成为VIP用户?查看行情>

    如何成为加V用户?

    提升链客指数,即可成为加V用户,等级越高享受权益特权越多查看行情>

    如何成为皇冠用户?

    认证成为讲师,即可成为加冠用户,加冠用户享受诸多权益特权查看行情>

    · 2019-06-26
    64阅读 · 0赞赏 · 0问答
  • Substrate链:在Substrate链上部署Ink智能合约

    围绕Parity的Substrate区块链框架的开发正在顺利进行,现在可以部署基于Ink的智能合约。 在访问通过Polkadot JS客户端调用智能合约函数的方法之前,本文将介绍Ink智能合约的编译和部署过程。测试Ink智能合约测试Ink智能合约可以(并且应该)在链下和链上进行。 先验可以通过智能合约本身内的测试模块完成,后者可以在本地Substrate dev链上完成。根据我的经验,在编译和部署合同之后,我发现了合同错误。强调了链上测试的重要性。这些错误成功地绕过了测试模块和编译过程,因此除了测试模块之外,还必须在测试链上测试整个契约。我们将进一步访问的polkadotJSUI允许我们轻松地完成这项工作。测试墨迹合同的第一种方法是通过contract!下的测试模块宏。样板文件如下:测试函数被包装在一个单独的tests模块中,该模块从父模块导入所有内容,从而了解有关智能合约的所有信息。让我们从顶部的cfg标志开始,分解一些更模糊的代码行。测试函数被包装在一个单独的tests模块中,该模块从父模块导入所有内容,从而了解有关智能合约的所有信息。让我们从顶部的cfg标志开始,分解一些更模糊的代码行。第一行,super::*非常简单;测试模块需要知道它正在测试的智能合约,因此所有内容都从父模块 - 智能合约本身带入*。 第二个参数将TryFrom特征带入范围。TryFrom特性实现了简单且安全的类型转换,在某些情况下可能会以受控方式失败。我们使用从TryFrom特征派生的try_from()方法来尝试获取AccountId地址以供我们的测试使用。 这实际上是我们在初始化合同实例后在it_works()测试中做的第一件事:Substrate中的AccountId由32个字符组成,因此Alice的地址简单地声明为32个零。解包该帐户以从Result或Error枚举中获取实际地址。在函数定义之前存在一个[test]语句;这是Rust语法,让编译器知道我们打算将此函数作为测试函数。 VS Code将在每个以这种方式标记为测试的功能下嵌入一个测试按钮 - 但是单击此按钮以调用cargo测试将失败,因为我们需要稍微修改的测试命令来测试Ink合同。我们将进一步访问该命令。在it_works()中,我们使用deploy_mock()初始化合同的可变实例,deploy_mock()是Ink框架提供的模拟部署功能。现在可以通过_nftoken变量调用和操作智能合约。 deploy_mock()将调用智能合约的deploy()方法 - 它需要一个init_value参数 - 因此提供了100的值,从而在测试运行时创建100个令牌。在测试中使用断言从这里,剩下的部分Works()很容易理解。我们利用了Rust的断言宏,以确保我们的合同状态如我们预期的那样在转移令牌和批准其他帐户发送令牌时发生变化。Rust包含三个可供我们在标准库中使用的断言宏:如果断言失败,测试功能也将失败,并在测试完成后报告为失败。 为了测试我们的Ink合约,我们运行以下命令:使用--no capture将提供更详细的输出,包括println()输出,其中它已在测试模块中使用。TEST ENV功能确保我们只测试Ink环境,如cargo.toml中所定义的:成功的测试将产生以下输出:编译智能合约通过测试,我们现在可以编译合同。 在项目目录中运行build.sh来执行此操作:生成的文件将位于target/文件夹中:Ink智能合约被编译到Web二进制标准WebAssembly或.wasm中。我们感兴趣的是上面编译输出中的两个文件,我们将上传到Substrate:nftoken-pruned.wasm:一个优化的.wasm文件,我们将上传到我们的Substrate链NFToken.json:JSON格式的合同ABI代码注意:尽管我们不关注WebAssembly,但值得一提的是,为了更高效的运行时,区块链空间中大量使用了这种格式。以太坊2.0将依赖于他们称为ewasm的Webassembly的一个子集,当然,Substrate链也采用了该标准。虽然Webassembly主要针对Web,但它绝不局限于浏览器。WebAssembly规范正在开发中,我们可以期望在未来几年发布更多的特性,这使得它成为一种非常有趣的技术。您可能熟悉基于以太坊的智能合约中的智能合约ABI,该合同为前端DAPPS提供了与链上合同通信的方式。它们本质上描述了智能合约的结构,包括它在JSON对象中的函数和变量,使得基于JavaScript的应用程序集成起来特别简单。现在,要部署合同,如果您还没有这样做,请启动您的本地Substrate链,然后让我们转向Polkadot JS应用程序来管理我们的部署。部署Ink智能合约在Substrate链上部署和实例化合同涉及首先部署合同,然后实例化它。 这个两步过程允许开发人员部署特定标准 - 可能是令牌标准 - 然后其他感兴趣的各方可以使用他们自己的令牌细节来实例化相同的合同。 这样就无需上传相同合同的副本,即可获得基本相同的功能和相同的ABI代码。重申一下,这两步过程包括:将合同上传到基板链实例化合同,然后可以与之交互Polkadot JS现在我们将把编译好的.wasm和.json abi上传到一个底层dev链。为此,需要使用polkadotJS客户机。您可以复制项目以在本地计算机上运行,也可以访问https://polkadot.js.org/apps以在线访问它。加载客户端以开始随后的部署过程。步骤1:确保客户端已连接到本地Substrate节点我们首先需要确保客户端连接到正确的链。导航到Settings选项卡,确保要连接的远程节点/端点设置为Local Node(127.0.0.1:9944)。如果需要更改,请点击保存并重新加载。注意:其他链,Alexander和Emberic Elm,是由Parity管理的基于底物的链。使用其他Substrate链(如Polkadot)超出了本文的范围,但是,Pokakdot JS客户端实际上设计用于任何基于Substrate的区块链,因此在整个应用程序中呈现的内容非常动态。第2步:将已编译的智能合约部署到您的节点上要部署我们的合同,请从侧栏导航到“contract”页面,并确保您位于“code”选项卡上。如果尚未在节点上部署合同,则“code”选项卡将是唯一可用的选项卡。用户界面将类似于以下内容:现在在Code选项卡上:确保部署帐户设置为ALICE。 Alice将有足够的余额来部署,实例化和测试合同将nftoken-pruned.wasm拖到已编译的合同WASM字段中可选:修改代码包名称值以获得更加人性化的名称将NFToken.json拖到contract ABI字段上将允许的最大气体设置为500,000,以确保我们提供足够的气体来处理交易配置完成后,点击Deploy,然后再次确认。 交易将进行,智能合约将被部署。步骤3:实例化合同您现在将注意到另外两个选项卡,Instance和Call。 我们将首先使用Instance选项卡实例化合同,然后使用Call选项卡来测试我们的功能。 Instance选项卡将类似于以下内容:在“instance”选项卡中:检查此code for this contract是否指向已部署的合同。将要生成的初始令牌金额设置为initValue值。注意:polkadot ui现在开始使用我们的智能合约结构,特别是需要为我们为智能合约定义的部署函数提供的参数,包括预期的数据类型。这是一个例子,说明了polkadot ui的动态特性,以及它是如何设计来满足各种智能合约类型的。将禀赋值设置为1,000,以确保新合同帐户具有某些值。这是官方Ink文档的建议值。与以太坊合同一样,墨水合同被部署到具有自己独特的AccountId和余额的单独地址。再次,将允许的maximum gas allowed设置为500000,以确保我们为交易提供足够的燃气。点击Initiate;并确认执行交易。成功交易后,合约现在将被实例化并且功能可以调用。第4步:从实例化合同中调用函数我们现在的最终工作是确保功能按预期工作。您会注意到我们在合同中定义的所有pub(external)函数现在都可以在Call选项卡中调用和测试:能够在Polkadot JS中调用合同函数Polkadot JS尚未提供来自客户端本身的调用的反馈,但您终端中的节点源应在新块验证时反映事务。 我们现在拥有的UX是成功或失败事件通知,它们会在处理函数调用时弹出在浏览器窗口的右上角。注意:反馈机制将在命令行或Polkadot JS客户端中在可用时发布。总结我们已经完成了从安装到链上实例化的Ink智能合约部署过程。作为一个简短的总结,让我们来看看使这个过程成为可能的各个部分:1、安装底层的Rust语言,Cargo包管理器和Substrate框架,2、Ink的安装,可通过自己的cargo进行访问,以及将Ink编译为.wasm所需的WebAssembly工具。3、引导基本的Flipper Ink合约以获取Ink样板,包括环境配置和build.sh文件4、编写符合Rust概念和惯例的NFToken合同,具有铸造,转移和批准功能,以及事件发布。5、在使用build.sh编译合同之前,通过测试模块进行测试。6、通过连接到本地Substrate dev链的Polkadot JS客户端部署,实例化和测试函数调用。

    区块链社区

    如何成为加VIP用户?

    VIP用户是链客特邀的行业权威和技术大咖,您想成为VIP用户?查看行情>

    如何成为加V用户?

    提升链客指数,即可成为加V用户,等级越高享受权益特权越多查看行情>

    如何成为皇冠用户?

    认证成为讲师,即可成为加冠用户,加冠用户享受诸多权益特权查看行情>

    · 2019-06-26
    75阅读 · 0赞赏 · 0问答
  • Goroutine调度策略

    在调度器概述一节我们提到过,所谓的goroutine调度,是指程序代码按照一定的算法在适当的时候挑选出合适的goroutine并放到CPU上去运行的过程。这句话揭示了调度系统需要解决的三大核心问题:调度时机:什么时候会发生调度?调度策略:使用什么策略来挑选下一个进入运行的goroutine?切换机制:如何把挑选出来的goroutine放到CPU上运行?对这三大问题的解决构成了调度器的所有工作,因而我们对调度器的分析也必将围绕着它们所展开。第二章我们已经详细的分析了调度器的初始化以及goroutine的切换机制,本章将重点讨论调度器如何挑选下一个goroutine出来运行的策略问题,而剩下的与调度时机相关的内容我们将在第4~6章进行全面的分析。再探schedule函数在讨论main goroutine的调度时我们已经见过schedule函数,因为当时我们的主要关注点在于main goroutine是如何被调度到CPU上运行的,所以并未对schedule函数如何挑选下一个goroutine出来运行做深入的分析,现在是重新回到schedule函数详细分析其调度策略的时候了。runtime/proc.go : 2467// One round of scheduler: find a runnable goroutine and execute it.// Never returns.func schedule() {    _g_ := getg()   //_g_ = m.g0    ......    var gp *g    ......       if gp == nil {    // Check the global runnable queue once in a while to ensure fairness.    // Otherwise two goroutines can completely occupy the local runqueue    // by constantly respawning each other.       //为了保证调度的公平性,每个工作线程每进行61次调度就需要优先从全局运行队列中获取goroutine出来运行,       //因为如果只调度本地运行队列中的goroutine,则全局运行队列中的goroutine有可能得不到运行        if _g_.m.p.ptr().schedtick%61 == 0 && sched.runqsize > 0 {            lock(&sched.lock) //所有工作线程都能访问全局运行队列,所以需要加锁            gp = globrunqget(_g_.m.p.ptr(), 1) //从全局运行队列中获取1个goroutine            unlock(&sched.lock)        }    }    if gp == nil {        //从与m关联的p的本地运行队列中获取goroutine        gp, inheritTime = runqget(_g_.m.p.ptr())        if gp != nil && _g_.m.spinning {            throw("schedule: spinning with local work")        }    }    if gp == nil {        //如果从本地运行队列和全局运行队列都没有找到需要运行的goroutine,        //则调用findrunnable函数从其它工作线程的运行队列中偷取,如果偷取不到,则当前工作线程进入睡眠,        //直到获取到需要运行的goroutine之后findrunnable函数才会返回。        gp, inheritTime = findrunnable() // blocks until work is available    }    ......    //当前运行的是runtime的代码,函数调用栈使用的是g0的栈空间    //调用execte切换到gp的代码和栈空间去运行    execute(gp, inheritTime)  }schedule函数分三步分别从各运行队列中寻找可运行的goroutine:第一步,从全局运行队列中寻找goroutine。为了保证调度的公平性,每个工作线程每经过61次调度就需要优先尝试从全局运行队列中找出一个goroutine来运行,这样才能保证位于全局运行队列中的goroutine得到调度的机会。全局运行队列是所有工作线程都可以访问的,所以在访问它之前需要加锁。第二步,从工作线程本地运行队列中寻找goroutine。如果不需要或不能从全局运行队列中获取到goroutine则从本地运行队列中获取。第三步,从其它工作线程的运行队列中偷取goroutine。如果上一步也没有找到需要运行的goroutine,则调用findrunnable从其他工作线程的运行队列中偷取goroutine,findrunnable函数在偷取之前会再次尝试从全局运行队列和当前线程的本地运行队列中查找需要运行的goroutine。下面我们先来看如何从全局运行队列中获取goroutine。从全局运行队列中获取goroutine从全局运行队列中获取可运行的goroutine是通过globrunqget函数来完成的,该函数的第一个参数是与当前工作线程绑定的p,第二个参数max表示最多可以从全局队列中拿多少个g到当前工作线程的本地运行队列中来。runtime/proc.go : 4663// Try get a batch of G's from the global runnable queue.// Sched must be locked.func globrunqget(_p_ *p, max int32) *g {    if sched.runqsize == 0 {  //全局运行队列为空        return nil    }    //根据p的数量平分全局运行队列中的goroutines    n := sched.runqsize / gomaxprocs + 1    if n > sched.runqsize { //上面计算n的方法可能导致n大于全局运行队列中的goroutine数量        n = sched.runqsize    }    if max > 0 && n > max {        n = max   //最多取max个goroutine    }    if n > int32(len(_p_.runq)) / 2 {        n = int32(len(_p_.runq)) / 2  //最多只能取本地队列容量的一半    }    sched.runqsize -= n    //直接通过函数返回gp,其它的goroutines通过runqput放入本地运行队列    gp := sched.runq.pop()  //pop从全局运行队列的队列头取    n--    for ; n > 0; n-- {        gp1 := sched.runq.pop()  //从全局运行队列中取出一个goroutine        runqput(_p_, gp1, false)  //放入本地运行队列    }    return gp}globrunqget函数首先会根据全局运行队列中goroutine的数量,函数参数max以及_p_的本地队列的容量计算出到底应该拿多少个goroutine,然后把第一个g结构体对象通过返回值的方式返回给调用函数,其它的则通过runqput函数放入当前工作线程的本地运行队列。这段代码值得一提的是,计算应该从全局运行队列中拿走多少个goroutine时根据p的数量(gomaxprocs)做了负载均衡。如果没有从全局运行队列中获取到goroutine,那么接下来就在工作线程的本地运行队列中寻找需要运行的goroutine。从工作线程本地运行队列中获取goroutine从代码上来看,工作线程的本地运行队列其实分为两个部分,一部分是由p的runq、runqhead和runqtail这三个成员组成的一个无锁循环队列,该队列最多可包含256个goroutine;另一部分是p的runnext成员,它是一个指向g结构体对象的指针,它最多只包含一个goroutine。从本地运行队列中寻找goroutine是通过runqget函数完成的,寻找时,代码首先查看runnext成员是否为空,如果不为空则返回runnext所指的goroutine,并把runnext成员清零,如果runnext为空,则继续从循环队列中查找goroutine。runtime/proc.go : 4825// Get g from local runnable queue.// If inheritTime is true, gp should inherit the remaining time in the// current time slice. Otherwise, it should start a new time slice.

    robzhang

    如何成为加VIP用户?

    VIP用户是链客特邀的行业权威和技术大咖,您想成为VIP用户?查看行情>

    如何成为加V用户?

    提升链客指数,即可成为加V用户,等级越高享受权益特权越多查看行情>

    如何成为皇冠用户?

    认证成为讲师,即可成为加冠用户,加冠用户享受诸多权益特权查看行情>

    · 2019-06-26
    154阅读 · 0赞赏 · 0问答
  • Go语言调度器之盗取goroutine-下

    工作线程进入睡眠分析完盗取过程,我们继续回到findrunnable函数。如果工作线程经过多次努力一直找不到需要运行的goroutine则调用stopm进入睡眠状态,等待被其它工作线程唤醒。runtime/proc.go : 1918// Stops execution of the current m until new work is available.// Returns with acquired P.func stopm() {    _g_ := getg()    if _g_.m.locks != 0 {        throw("stopm holding locks")    }    if _g_.m.p != 0 {        throw("stopm holding p")    }    if _g_.m.spinning {        throw("stopm spinning")    }    lock(&sched.lock)    mput(_g_.m)   //把m结构体对象放入sched.midle空闲队列    unlock(&sched.lock)    notesleep(&_g_.m.park)  //进入睡眠状态     //被其它工作线程唤醒    noteclear(&_g_.m.park)    acquirep(_g_.m.nextp.ptr())    _g_.m.nextp = 0}stopm的核心是调用mput把m结构体对象放入sched的midle空闲队列,然后通过notesleep(&m.park)函数让自己进入睡眠状态。note是go runtime实现的一次性睡眠和唤醒机制,一个线程可以通过调用notesleep(*note)进入睡眠状态,而另外一个线程则可以通过notewakeup(*note)把其唤醒。note的底层实现机制跟操作系统相关,不同系统使用不同的机制,比如linux下使用的futex系统调用,而mac下则是使用的pthread_cond_t条件变量,note对这些底层机制做了一个抽象和封装,这种封装给扩展性带来了很大的好处,比如当睡眠和唤醒功能需要支持新平台时,只需要在note层增加对特定平台的支持即可,不需要修改上层的任何代码。回到stopm,当从notesleep函数返回后,需要再次绑定一个p,然后返回到findrunnable函数继续重新寻找可运行的goroutine,一旦找到可运行的goroutine就会返回到schedule函数,并把找到的goroutine调度起来运行,如何把goroutine调度起来运行的代码我们已经分析过了。现在继续看notesleep函数。runtime/lock_futex.go : 139func notesleep(n *note) {    gp := getg()    if gp != gp.m.g0 {        throw("notesleep not on g0")    }    ns := int64(-1)  //超时时间设置为-1,表示无限期等待    if *cgo_yield != nil {        // Sleep for an arbitrary-but-moderate interval to poll libc interceptors.        ns = 10e6    }     //使用循环,保证不是意外被唤醒    for atomic.Load(key32(&n.key)) == 0 {        gp.m.blocked = true        futexsleep(key32(&n.key), 0, ns)        if *cgo_yield != nil {            asmcgocall(*cgo_yield, nil)        }        gp.m.blocked = false    }}notesleep函数调用futexsleep进入睡眠,这里之所以需要用一个循环,是因为futexsleep有可能意外从睡眠中返回,所以从futexsleep函数返回后还需要检查note.key是否还是0,如果是0则表示并不是其它工作线程唤醒了我们,只是futexsleep意外返回了,需要再次调用futexsleep进入睡眠。futexsleep调用futex函数进入睡眠。runtime/os_linux.go : 32// Atomically,//if(*addr == val) sleep// Might be woken up spuriously; that's allowed.// Don't sleep longer than ns; ns < 0 means forever.//go:nosplitfunc futexsleep(addr *uint32, val uint32, ns int64) {    var ts timespec    // Some Linux kernels have a bug where futex of    // FUTEX_WAIT returns an internal error code    // as an errno. Libpthread ignores the return value    // here, and so can we: as it says a few lines up,    // spurious wakeups are allowed.    if ns < 0 {        //调用futex进入睡眠        futex(unsafe.Pointer(addr), _FUTEX_WAIT_PRIVATE, val, nil, nil, 0)        return    }    // It's difficult to live within the no-split stack limits here.    // On ARM and 386, a 64-bit divide invokes a general software routine    // that needs more stack than we can afford. So we use timediv instead.    // But on real 64-bit systems, where words are larger but the stack limit    // is not, even timediv is too heavy, and we really need to use just an    // ordinary machine instruction.    if sys.PtrSize == 8 {        ts.set_sec(ns / 1000000000)        ts.set_nsec(int32(ns % 1000000000))    } else {        ts.tv_nsec = 0        ts.set_sec(int64(timediv(ns, 1000000000, (*int32)(unsafe.Pointer(&ts.tv_nsec)))))    }    futex(unsafe.Pointer(addr), _FUTEX_WAIT_PRIVATE, val, unsafe.Pointer(&ts), nil, 0)}futex是go汇编实现的函数,主要功能就是执行futex系统调用进入操作系统内核进行睡眠。runtime/sys_linux_amd64.s : 525// int64 futex(int32 *uaddr, int32 op, int32 val,//struct timespec *timeout, int32 *uaddr2, int32 val2);TEXT runtime·futex(SB),NOSPLIT,$0   #下面的6条

    robzhang

    如何成为加VIP用户?

    VIP用户是链客特邀的行业权威和技术大咖,您想成为VIP用户?查看行情>

    如何成为加V用户?

    提升链客指数,即可成为加V用户,等级越高享受权益特权越多查看行情>

    如何成为皇冠用户?

    认证成为讲师,即可成为加冠用户,加冠用户享受诸多权益特权查看行情>

    · 2019-06-26
    131阅读 · 0赞赏 · 0问答
  • Go语言调度器之盗取goroutine-上

    从全局运行队列与工作线程的本地运行队列获取goroutine的过程,这一小节我们继续分析因无法从上述两个队列中拿到需要运行的goroutine而导致的从其它工作线程的本地运行队列中盗取goroutine的过程。findrunnable() 函数负责处理与盗取相关的逻辑,该函数代码很繁杂,因为它还做了与gc和netpoll等相关的事情,为了不影响我们的分析思路,这里我们仍然把不相关的代码删掉了,不过代码还是比较多,但总结起来就一句话:尽力去各个运行队列中寻找goroutine,如果实在找不到则进入睡眠状态。下面是代码细节:runtime/proc.go : 2176// Finds a runnable goroutine to execute.// Tries to steal from other P's, get g from global queue, poll network.func findrunnable() (gp *g, inheritTime bool) {    _g_ := getg()    // The conditions here and in handoffp must agree: if    // findrunnable would return a G to run, handoffp must start    // an M.top:    _p_ := _g_.m.p.ptr()    ......    // local runq    //再次看一下本地运行队列是否有需要运行的goroutine    if gp, inheritTime := runqget(_p_); gp != nil {        return gp, inheritTime    }    // global runq    //再看看全局运行队列是否有需要运行的goroutine    if sched.runqsize != 0 {        lock(&sched.lock)        gp := globrunqget(_p_, 0)        unlock(&sched.lock)        if gp != nil {            return gp, false        }    }    ......    // Steal work from other P's.    //如果除了当前工作线程还在运行外,其它工作线程已经处于休眠中,那么也就不用去偷了,肯定没有    procs := uint32(gomaxprocs)    if atomic.Load(&sched.npidle) == procs-1 {        // Either GOMAXPROCS=1 or everybody, except for us, is idle already.        // New work can appear from returning syscall/cgocall, network or timers.        // Neither of that submits to local run queues, so no point in stealing.        goto stop    }    // If number of spinning M's >= number of busy P's, block.    // This is necessary to prevent excessive CPU consumption    // when GOMAXPROCS>>1 but the program parallelism is low.    // 这个判断主要是为了防止因为寻找可运行的goroutine而消耗太多的CPU。    // 因为已经有足够多的工作线程正在寻找可运行的goroutine,让他们去找就好了,自己偷个懒去睡觉    if !_g_.m.spinning && 2*atomic.Load(&sched.nmspinning) >= procs-atomic.Load(&sched.npidle) {        goto stop    }    if !_g_.m.spinning {        //设置m的状态为spinning        _g_.m.spinning = true        //处于spinning状态的m数量加一        atomic.Xadd(&sched.nmspinning, 1)    }       //从其它p的本地运行队列盗取goroutine    for i := 0; i < 4; i++ {        for enum := stealOrder.start(fastrand()); !enum.done(); enum.next() {            if sched.gcwaiting != 0 {                goto top            }            stealRunNextG := i > 2 // first look for ready queues with more than 1 g            if gp := runqsteal(_p_, allp[enum.position()], stealRunNextG); gp != nil {                return gp, false            }        }    }stop:    ......    // Before we drop our P, make a snapshot of the allp slice,    // which can change underfoot once we no longer block    // safe-points. We don't need to snapshot the contents because    // everything up to cap(allp) is immutable.    allpSnapshot := allp    // return P and block    lock(&sched.lock)     ......     if sched.runqsize != 0 {        gp := globrunqget(_p_, 0)        unlock(&sched.lock)        return gp, false    }       // 当前工作线程解除与p之间的绑定,准备去休眠    if releasep() != _p_ {        throw("findrunnable: wrong p")    }    //把p放入空闲队列    pidleput(_p_)    unlock(&sched.lock)// Delicate dance: thread transitions from spinning to non-spinning state,// potentially concurrently with submission of new goroutines. We must// drop nmspinning first and then check all per-P queues again (with// #StoreLoad memory barrier in between). If we do it the other way around,// another thread can submit a goroutine after we've checked all run queues// but before we drop nmspinning; as the result nobody will unpark a thread// to run the goroutine.// If we discover new work below, we need to restore m.spinning as a signal// for resetspinning to unpark a new worker thread (because there can be more// than one starving goroutine). However, if after discovering new work// we also observe no idle Ps, it is OK to just park the current thread:// the system is fully loaded so no spinning threads are required.// Also see "Worker thread parking/unparking" comment at the top of the file.    wasSpinning := _g_.m.spinning    if _g_.m.spinning {        //m即将睡眠,状态不再是spinning        _g_.m.spinning = false        if int32(atomic.Xadd(&sched.nmspinning, -1)) 

    robzhang

    如何成为加VIP用户?

    VIP用户是链客特邀的行业权威和技术大咖,您想成为VIP用户?查看行情>

    如何成为加V用户?

    提升链客指数,即可成为加V用户,等级越高享受权益特权越多查看行情>

    如何成为皇冠用户?

    认证成为讲师,即可成为加冠用户,加冠用户享受诸多权益特权查看行情>

    · 2019-06-26
    150阅读 · 0赞赏 · 0问答
  • 比特币算力继续创下新高,相当于至少有60多万台矿机开机。

    ChivalryNonsense大侠瞎BB:BTC突破10000美元之后继续延续小碎步上涨的节奏,随着BTC价格的上涨,BTC算力也迎来了高速增长,最新的数据显示BTC最近一天的全网平均算力达到了65.26EH/S,持续创造历史新高,仅6月23日一天算力增幅就达到了20%,下图就是BTC的每日平均算力走势。很多人可能并不知道20%的算力增幅意味着什么,大侠和大家简单的算一笔账。BTC全网算力的涨跌总体来说是和BTC的价格呈正相关的,BTC价格越高,全网算力就会越高,反之亦然,所以不光是二级市场的韭菜喜欢追涨杀跌,矿工群体也是一样,BTC突破10000美元,会有大量的新韭菜进军市场,以前暂时退出市场的一部分人也会回来。矿工这一群体表现的尤为明显,可以大概算一算,20%的算力增幅大约是11EH/S,我们拿现在市场上比较畅销的蚂蚁矿机S9SE来举例,一台矿机的算力是16TH/S,这个算力的单位换算是1EH/S=1000PH/S、1PH/S=1000TH/S这样换算下来就相当于在一天内至少有690000台蚂蚁矿机S9SE重新开机,按照其官网价格2650元来算,增加这么多台矿机的成本就高达18亿,而实际上这款矿机官网早已售罄,在二手市场上买都是会有溢价的,再加上场地、人工、电费等成本,就BTC破万这几天矿工这一群体就有至少20亿以上的资金进场淘金,由此也能看出10000美元这个心理价位影响有多大。只要BTC的价格维持在10000美元以上,会有源源不断的新鲜血液注入市场,不过老韭菜应该都能注意到,近期虽然比特币突飞猛进,但市场整体赚钱效应不佳,总是缺少一点什么的感觉,这点也许只有在这个市场里玩了至少一两年的老韭菜能感觉到。大家观察市场也能发现,今年市场上的山寨币基本无人问津,涨得比较多的一部分是有利好预期的山寨币,这点说明团队至少还在,另一部分上涨幅度大的就是今年才上线的新山寨币,而很多老的山寨币基本没动,很多或许连项目方本身都已经不存在了。对于新进场的韭菜来说,很少会选择主流币和BTC,因为新韭菜什么都不动,他们第一反应是价格高的不买,而那些单价低的山寨币又有一定知名度的token就会成为他们的首选,但是同样前期在市场上获利的人也很可能在这个时候选择落袋为安,因此随着行情的普涨,大规模的洗盘行情也随时都会到来。6-25-分析1BTC昨日大饼强势突破震荡区间并再次冲破前期高点,主流币种按照各自的走势震荡调整并未跟随,其原因有两方面:1、场外流入的资金没有选择主流梯队;2、场内资金还没有达成高度统一,活跃的资金还不足以支撑整个市场整体上行。因此后市主流梯队启动有可能出现的两种市场环境,第一种:大饼独行后仍然面临冲高后回落到震荡区间的可能,回落后保持区间震荡走势,如回落测试10000美元附近,大饼资金呈现流出后再注入到主流梯队当中。第二种:大饼继续强势拉升,突破到12000美元上方,继续激活市场热度,场内资金形成高度统一的逐涨,造成主流梯队陆续补涨。至于大侠更倾向于第一种,整体操作策略前几日已经做了明确部署。当然还存在第三种情况就是大饼上攻后选择大幅回调跌破最近几日的震荡区间,主流币跟随回调,这就是大侠建议大家操作上匹配一个强势和一个滞涨主流币各3层仓位的原因,我们目前依然不去重仓押注,预防第三种情况出现而留有的补仓机会。今日分析:大饼再次向上突破震荡区间,上攻到震荡区间上沿出现乏力迹象,短期回落到前期震荡区间的概率较大,届时主流币种跟随大饼回试一段,而后主流币或将有机会走一段较强力度的向上走势,大饼短期支撑位:10500美元,压力位:11500美元。2主流梯队EOS:弱势震荡走势,后期大概率沿4小时MA30均线震荡,震荡结束后有望走一波较强反弹,短期支撑位:7美元,压力位:7.6美元。ETH:近期表现较佳的主流币种,前日按照提示在回踩MA5均线是介入的均价大概在300美元附近,可继续持有。震荡结束后向上逃离震荡区间的机会很大,短期支撑位:300美元,压力位:320美元。ADA:突破0.1美元几次未果,浮筹较为松动,短期内有震荡消化浮筹的需求,震荡结束后有望突破0.1美元压制去到高一层的台阶。短期支持位:0.094美元,压力位:0.1美元。BCH:今日盘面与昨日变化不大,短期内继续维持区间震荡,460美元作为短期震荡下沿线的支撑,看好后市的可对应回补部分仓位。震荡完成有望上攻500美元。压力位:490美元。XRP:走势符合昨日分析,沿4小时图形MA20震荡,后期震荡缓慢向上的概率较大,保持再次冲击0.5美元颈线位的动能,短期支撑位:0.45美元,压力位:0.5美元。ZEC:短期内保持区间震荡,震荡结束后大概率将会向上突破前高开启新的拉升走势,灵活做T的可自行参考支撑回补。短期支撑位:104美元,压力位:115美元3关注板块:BTM:震荡走势始终维持在0.18美元上方,继续回踩0.18美元之后近期有机会逐步震荡向上冲击前面的高点0.21美元。短期支撑位:0.18美元。ONT:沿5日线震荡上移,昨日也对ONT做出了解释,同BTM和QTUM作为对比,大家也可以回看QTUM突破颈线位3.8美元之后的走势。那么对于本体来说,颈线位在1.7美元附近,最近两个月冲击了5次都未成功,关注今日的力度,有效突破之后可打开向上的瓶颈,中长线的持有即可。短期支撑位:1.5美元,压力位:1.7美元

    大侠区块链

    如何成为加VIP用户?

    VIP用户是链客特邀的行业权威和技术大咖,您想成为VIP用户?查看行情>

    如何成为加V用户?

    提升链客指数,即可成为加V用户,等级越高享受权益特权越多查看行情>

    如何成为皇冠用户?

    认证成为讲师,即可成为加冠用户,加冠用户享受诸多权益特权查看行情>

    · 2019-06-25
    145阅读 · 0赞赏 · 0问答
  • 国外乌兹别克斯坦矿场托管,全年0.3元起 !!!

    乌兹别克斯坦矿场托管全年含运维电价0.3元起7月底通电300台起托无任何套路费用第二期仅剩1500个机位我公司为当地第四家正规审批的数字货币矿业公司(前三家为俄罗斯,韩国企业)19920004841

    区块链-lxy

    如何成为加VIP用户?

    VIP用户是链客特邀的行业权威和技术大咖,您想成为VIP用户?查看行情>

    如何成为加V用户?

    提升链客指数,即可成为加V用户,等级越高享受权益特权越多查看行情>

    如何成为皇冠用户?

    认证成为讲师,即可成为加冠用户,加冠用户享受诸多权益特权查看行情>

    · 2019-06-25
    137阅读 · 0赞赏 · 0问答
推荐笔记
作者周榜

使用LK token投放广告!!