嘿!您似乎在 United States,您想使用我们的 English 网站吗?
Switch to English site
Skip to main content

RS IoT区块链演示器第4部分:区块链网络

Main25_ee73fbb2934c0cb4128dffe2723449559ac0a4e1.jpg

创建专用区块链网络并为其部署分布式应用程序。

这一系列文章着眼于为两年一度的Electronica交易会和会议设计和构建一组示范者,展示了区块链技术如何用于创建安全,分散的数据平台以及更多物联网。

在这篇文章中,我们将了解如何建立一个使用权威证明(PoA)来保护它的私有以太坊网络,然后将分布式应用程序(DApps)部署到这个支持四种不同物联网的新网络中用例。

验证的权威

区块链网络是点对点的,因此没有中央服务器。但是,它们通过加密和节点保持安全,这些节点“密封”包含一个或多个事务的块。对于大多数公共区块链网络,通过工作量证明获得密封块的权利,其中节点选择作为矿工操作并执行一些高度计算密集型的任务。

在私有区块链网络中,让节点不必要地浪费能量,执行一些最终无用的任务以获得密封新块的权利是没有意义的。事实上,许多公共网络也在寻求更环保,更坦诚,更明智的替代方案,其中一种机制就是权威证明。

使用PoA,我们需要做的是,在区块链初始化时,指定有权密封新块的帐户的地址。然后,将在设置为作为矿工运行的网络节点上配置这些帐户。在我们的例子中,这只是一个帐户和一个节点。

节点和帐户

有许多可用的以太坊节点实现,我们决定使用Go语言以太坊客户端geth。安装完成后,我们在每个节点上创建帐户:

geth --datadir /data/bc/ account new

在初始化网络时,将需要每个新帐户的地址。

成因块

{
  "config": {
    "chainId": 555,
    "homesteadBlock": 1,
    "eip150Block": 2,
    "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "eip155Block": 3,
    "eip158Block": 3,
    "byzantiumBlock": 4,
    "clique": {
      "period": 5,
      "epoch": 30000
    }
  },
  "nonce": "0x0",
  "timestamp": "0x5bb8bea5",
  "extraData": "0x00000000000000000000000000000000000000000000000000000000000000004ae82f919e03741ce8e69c108ea25438b218d6680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  "gasLimit": "0x59A5380",
  "difficulty": "0x1",
  "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "alloc": {
    "4ae82f919e03741ce8e69c108ea25438b218d668": {
      "balance": "0x200000000000000000000000000000000000000000000000000000000000000"
    },
    "478f2c61e4eb1c09596a7af138b94ae598de32c0": {
      "balance": "0x200000000000000000000000000000000000000000000000000000000000000"
    },
    "2bc19750cdf3991d0a27d45304276cd4d71f6975": {
      "balance": "0x200000000000000000000000000000000000000000000000000000000000000"
    },
    "3adb96d017239642e7b87ea816dd6171581f1d3a": {
      "balance": "0x200000000000000000000000000000000000000000000000000000000000000"
    },
    "7b0975783ee29b5416acac1d47b29908a06322fe": {
      "balance": "0x200000000000000000000000000000000000000000000000000000000000000"
    }
  },
  "number": "0x0",
  "gasUsed": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}

区块链必须从某个地方开始,它与块0,即创世块。这是我们指定基本网络参数的地方,包括PoA授权密封新区块的账户地址,以及我们希望预先分配资金的账户地址。

上面可以看到我们的genesis块的JSON配置。 chainId很重要,用于唯一标识我们的网络。 extraData参数中嵌入的地址是我们希望授权密封新块的帐户的地址。

5周期意味着我们希望每隔5秒钟封一个新区块。这似乎是等待提交待决事务的时间很长,并且与例如发布/发送消息或传统数据库,它是。但是,在公共网络中,它甚至可能需要数小时或数天。重要的是要记住,这不是瞬时的,并且应该通过其他机制满足任何实时要求,例如: MQTT发布/订阅消息。相反,依靠区块链来提供长期的,加密安全的,不可变的记录。

最后,alloc中指定的地址和余额用于预先分配资金。

希望参与我们网络的每个节点然后将初始化创世块:

geth --datadir /data/bc init iotbc.json

当节点启动并开始相互通信时,它们将不会形成或加入网络,除非它们已使用完全相同的创建块进行初始化。

资金?

尽管运营私有区块链网络并且对财富积累不感兴趣,我们仍然需要资金或以太网,因为这是以太坊网络运营的基础。原因很简单,如果交易是完全免费的,那么导致拒绝服务将是微不足道的,区块链数据库很快就会变得很大 - 充满虚假交易和参与网络的所有节点花费他们所有的时间来验证所述交易。因此,交易必须有成本。

如果要在以太网中指定交易成本,这将直接将其与高度动态 - 在公共网络中,至少 - 加密货币的价值联系起来。因此,我们有一个称为气体的单元,它与以太网分离,并且更加稳定。当然,给定数量的天然气仍将具有以太网成本,因此我们需要资金才能进行交易。

需要明确的是,我们可以在初始化区块链网络时为帐户分配尽可能多的Ether。此外,这些账户可以作为一种银行,随后在需要时将以太网分配给其他账户。因此,例如,在由服务提供商运营的生产网络中,他们可以最初保存所有以太网,然后随着时间的推移根据服务级别协议,订购或购买的信用等将其分配给用户。

为了绝对清楚,这种货币只对我们的私人网络有价值,并且不需要实际/法定货币来获取或分配它。

分布式应用

以太坊平台提供的不仅仅是记录交易的手段,它的分布式应用程序,即智能合约,开辟了一个充满可能性的世界。简而言之,这些是使用一种名为Solidity的语言开发的应用程序,它本身基于JavaScript,并且被开采到区块链上。换句话说,区块链成为一种分布式“应用程序商店”,应用程序可以充分利用其功能。

就像最终用户帐户一样,智能合约有一个地址,这是在部署和挖掘到区块链时生成的。如果我们知道地址及其应用程序二进制接口(ABI)定义,我们就可以与智能合约进行交互。阅读状态,例如变量是免费的,因为它不会更新区块链。但是,任何涉及更新区块链的操作都会产生与之相关的燃气成本,而且越复杂,成本就越高。

智能合约对他们自己来说是一个完整的主题,在这里我们只考虑基础知识。

物联网智能合约

每个用例我们将有一个智能合约,尽管没有理由不能拥有一个具有各种功能的智能合约来支持不同的用例。

我们的智能合约非常简单,每个允许我们设置并获得单个变量的值。因此,它们不提供对历史值的直接访问,但当然,它们保留在区块链中,并且可以在任何给定的块编号处读取变量状态。

另一种方法是使用数组,每次都向数组添加一个新值。

车祸

pragma solidity ^0.4.10;

contract CarCrash {
    address owner;
    address insurer;
    int impact;

    function CarCrash() {
        owner = 0x2BC19750cdf3991D0A27d45304276Cd4D71F6975;
        insurer = 0x4aE82F919e03741cE8E69C108ea25438b218d668;
    }

    function setImpact(int _impact) {
        require(msg.sender == owner);
        impact = _impact;
    }

    function getImpact() constant returns (int) {
        require(msg.sender == insurer);
        return impact;
    }
}

以上是CarCrash智能合约的Solidity代码。在此,我们定义了两个地址变量,名称为owner和insurer,它们被设置为Car Crash演示器单元和Miner上配置的帐户的地址。然后,我们定义允许我们设置和获取变量名称影响的函数,只有所有者帐户可以设置并且允许保险公司帐户获得。

我们不必在这些功能上配置这样的约束,当然保险公司可能会有一个帐户,或者实际上是在矿工以外的系统上配置的一些帐户。这只是为了了解可能的事情。

在实践中,智能合约可能更复杂,甚至可能依赖于其他智能合约并与之互动。

机器故障

MachineFailure合约几乎相同,只有函数名为 setLastFailuregetLastFailure,它们对变量  lastFailure进行操作。此外,所有者地址的值与计算机故障演示单元上配置的帐户的值不同。

温度警报和泄漏杀手

这里的变化非常相似,契约代替名为TemperatureAlert and LeakKiller并且适当地命名了函数和变量。

编译和部署

var CarCrash = artifacts.require("./CarCrash.sol");
var MachineFailure = artifacts.require("./MachineFailure.sol");
var TemperatureAlert = artifacts.require("./TemperatureAlert.sol");
var LeakKiller = artifacts.require("./LeakKiller.sol");

module.exports = function(deployer) {
  deployer.deploy(CarCrash)
    .then(() => console.log(CarCrash.address));
  deployer.deploy(MachineFailure)
    .then(() => console.log(MachineFailure.address));
  deployer.deploy(TemperatureAlert)
    .then(() => console.log(TemperatureAlert.address));
  deployer.deploy(LeakKiller)
    .then(() => console.log(LeakKiller.address));

合同被编译并随后使用Truffle,一个开发环境,测试框架和智能合约的更多部署到区块链。要使用它我们:

  1. 处理包含每个智能合约的文件
  2. 处理一个名为2_deploy_contracts.js 的简单文件(见上下文)
  3. 编辑 truffle.js 文件以提供我们的iotbc网络的详细信息(见下文)
module.exports = {
  networks: {
    iotbc: {
      host: "127.0.0.1",
      port: "8545",
      network_id: "555"
    }
  }
};

有了这个,我们就可以简单地输入truffle compile来编译智能合约。然后假设我们的以太坊节点正在运行且配置的帐户具有以太网,我们可以键入truffle migrate来部署这些并将它们挖掘到区块链上。为什么我们需要以太?由于我们实际上正在写区块链,我们需要花费天然气。

在部署每个智能合约时,其地址将记录到控制台,必须注意。

ABI

  "abi": [
    {
      "inputs": [],
      "payable": false,
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "constant": false,
      "inputs": [
        {
          "name": "_impact",
          "type": "int256"
        }
      ],
      "name": "setImpact",
      "outputs": [],
      "payable": false,
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "constant": true,
      "inputs": [],
      "name": "getImpact",
      "outputs": [
        {
          "name": "",
          "type": "int256"
        }
      ],
      "payable": false,
      "stateMutability": "view",
      "type": "function"
    }
  ]

为了与智能合约进行交互,我们不仅需要其地址,还需要其应用程序二进制接口。以上可以看出CarCrash智能合约的ABI。有了这两个,我们就可以用我们喜欢的任何语言编写用户应用程序,前提是可以通过localhost与以太网节点通过TCP进行通信。

总结

所以回顾一下:

  • 创建了一个私人区块链网络,不会浪费能源

  • 授权矿工密封块(实际上可能有很多)

  • 预先分配的资金到矿工账户和演示单位

  • 创建了四个智能合约

  • 编译合同并将它们部署到区块链

  • 注意到每个智能合约的地址和ABI

在下一篇文章中,我们将看看Python应用程序代码,它读取传感器和按钮,驱动以太坊LED,当然,还可以调用智能合约中的函数来更新区块链。

本系列的其他帖子

在总共五个部分的课程中涵盖了示范者的设计和建造:

Andrew Back

点击了解我们的连接支架是如何构建的

Open source (hardware and software!) advocate, Treasurer and Director of the Free and Open Source Silicon Foundation, organiser of Wuthering Bytes technology festival and founder of the Open Source Hardware User Group.