您正在查看: 2021年5月

eth goerli 测试网RPC

公开得RPC

https://goerli.prylabs.net/
https://rpc.goerli.mudit.blog/
https://rpc.slock.it/goerli
https://www.ethercluster.com/goerli
https://services.fault.dev/

infura注册节点

https://infura.io/

自己搭建同步节点

下载geth

https://geth.ethereum.org/downloads/

运行

nohup ./*geth --goerli --datadir=./ethdata --syncmode "fast" --cache 4096 --rpc --rpcaddr 0.0.0.0 --rpcport 19000 --rpcapi eth,net,web3 &

Swarm激励模型合约

源代码:https://github.com/ethersphere/swap-swear-and-swindle

Swarm目前只跑在Goerli测试网,核心的合约为ERC20SimpleSwap,源代码在master分支,对于后续功能合约 full Swap, Swear and Swindle相关代码在experimental分支

逻辑简述

目前Swarm的Goerli测试网部署的合约逻辑为
用户通过执行SimpleSwapFactory合约,部署ERC20SimpleSwap合约,并与发行的gBZZ代币交互

用户与Swarm交互

测试用户

0x10210572d6b4924Af7Ef946136295e9b209E1FA0

部署ERC20SimpleSwap合约

用户地址通过执行SimpleSwapFactory合约的deploySimpleSwap方法,完成部署ERC20SimpleSwap合约,通过查看交易的eventlog,部署的Chequebook合约地址为0x68f7ea9f3fae55e3e55fee0f0761b7df570fd212

deploySimpleSwap合约代码

function deploySimpleSwap(address issuer, uint defaultHardDepositTimeoutDuration)
  public returns (address) {
    address contractAddress = address(new ERC20SimpleSwap(issuer, ERC20Address, defaultHardDepositTimeoutDuration));
    deployedContracts[contractAddress] = true;
    emit SimpleSwapDeployed(contractAddress);
    return contractAddress;
  }

deploySimpleSwap执行同时完成了ERC20SimpleSwap的构造初始化

constructor(address _issuer, address _token, uint _defaultHardDepositTimeout) public {
    issuer = _issuer;
    token = ERC20(_token);
    defaultHardDepositTimeout = _defaultHardDepositTimeout;
  }

同时初始化了交互Token gBZZ代币

订金(为支票薄提供资金)

通过执行API进行为支票薄提供资金
http://localhost:1635/chequebook/deposit?amount=1000000000
执行的逻辑为用户地址0x10210572d6b4924af7ef946136295e9b209e1fa0向自己的Chequebook合约地址0x68f7ea9f3fae55e3e55fee0f0761b7df570fd212转对应数量的gBZZ,也可以理解成充值抵押

测试交易

https://goerli.etherscan.io/tx/0x81080bdc2ee4ede8898f003c4b74c9dcabdd6467e443f9ab8669f0c62434aaee

提现

将自己Chequebook合约中的gBZZ体现到用户地址
执行逻辑为执行自己的Chequebook合约地址0x68f7ea9f3fae55e3e55fee0f0761b7df570fd212中的withdraw方法。

合约代码

function withdraw(uint amount) public {
    /* 只有发行人可以做到这一点 */
    require(msg.sender == issuer, "not issuer");
    /* 确保我们不从保证金中提取任何东西 */
    require(amount <= liquidBalance(), "liquidBalance not sufficient");
    require(token.transfer(issuer, amount), "transfer failed");
  }

测试交易

https://goerli.etherscan.io/tx/0x967fabac2da76d868a9f80d8a64baacbe2cb585519388a4494593705ef050421

分析ERC20SimpleSwap合约

// SPDX-License-Identifier: BSD-3-Clause
pragma solidity =0.7.6;
pragma abicoder v2;
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/math/Math.sol";
import "@openzeppelin/contracts/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/presets/ERC20PresetMinterPauser.sol";


/**
@title支票簿合同,无豁免
@author The Swarm作者
@notice支票簿合同允许支票簿的发行者将支票发送到无限数量的交易对手。
此外,可以通过hardDeposits保证偿付能力
@dev作为发行人,如果发送的支票的累积价值高于所有存款的累积价值,则不应该发送任何支票
作为受益人,我们应始终考虑支票弹跳的可能性(当未分配hardDeposits时)
*/
contract ERC20SimpleSwap {
  using SafeMath for uint;

  event ChequeCashed(
    address indexed beneficiary,
    address indexed recipient,
    address indexed caller,
    uint totalPayout,
    uint cumulativePayout,
    uint callerPayout
  );
  event ChequeBounced();
  event HardDepositAmountChanged(address indexed beneficiary, uint amount);
  event HardDepositDecreasePrepared(address indexed beneficiary, uint decreaseAmount);
  event HardDepositTimeoutChanged(address indexed beneficiary, uint timeout);
  event Withdraw(uint amount);

  uint public defaultHardDepositTimeout;
  /* 跟踪每个受益人的硬存款(偿付能力的链上保证)的结构*/
  struct HardDeposit {
    uint amount; /* 分配的硬存款金额 */
    uint decreaseAmount; /* 减少量从请求减少时的金额中减去 */
    uint timeout; /* 发行者必须等待超时秒数才能减少hardDeposit,0表示应用defaultHardDepositTimeout */
    uint canBeDecreasedAt; /* 可以减少硬质沉积的时间点 */
  }

  struct EIP712Domain {
    string name;
    string version;
    uint256 chainId;
  }

  bytes32 public constant EIP712DOMAIN_TYPEHASH = keccak256(
    "EIP712Domain(string name,string version,uint256 chainId)"
  );
  bytes32 public constant CHEQUE_TYPEHASH = keccak256(
    "Cheque(address chequebook,address beneficiary,uint256 cumulativePayout)"
  );
  bytes32 public constant CASHOUT_TYPEHASH = keccak256(
    "Cashout(address chequebook,address sender,uint256 requestPayout,address recipient,uint256 callerPayout)"
  );
  bytes32 public constant CUSTOMDECREASETIMEOUT_TYPEHASH = keccak256(
    "CustomDecreaseTimeout(address chequebook,address beneficiary,uint256 decreaseTimeout)"
  );

  // 该合同使用的EIP712域
  function domain() internal pure returns (EIP712Domain memory) {
    uint256 chainId;
    assembly {
      chainId := chainid()
    }
    return EIP712Domain({
      name: "Chequebook",
      version: "1.0",
      chainId: chainId
    });
  }

  // 计算EIP712域分隔符。 这不能恒定,因为它取决于chainId
  function domainSeparator(EIP712Domain memory eip712Domain) internal pure returns (bytes32) {
    return keccak256(abi.encode(
        EIP712DOMAIN_TYPEHASH,
        keccak256(bytes(eip712Domain.name)),
        keccak256(bytes(eip712Domain.version)),
        eip712Domain.chainId
    ));
  }

  // 使用EIP712签名方案恢复签名
  function recoverEIP712(bytes32 hash, bytes memory sig) internal pure returns (address) {
    bytes32 digest = keccak256(abi.encodePacked(
        "\x19\x01",
        domainSeparator(domain()),
        hash
    ));
    return ECDSA.recover(digest, sig);
  }

  /* 此支票簿针对其写支票的令牌 */
  ERC20 public token;
  /* 将每个受益人与已支付给他们的款项相关联 */
  mapping (address => uint) public paidOut;
  /* 支付总额 */
  uint public totalPaidOut;
  /* 将每个受益人与他们的HardDeposit相关联 */
  mapping (address => HardDeposit) public hardDeposits;
  /* 所有硬存款的总和 */
  uint public totalHardDeposit;
  /* 合同的签发人,在施工中 */
  address public issuer;
  /* 指示支票是否在过去退回 */
  bool public bounced;

  /**
  @notice设置颁发者,令牌和defaultHardDepositTimeout。 只能被调用一次。
   @param _issuer此支票簿的支票的发行者(需要作为“将支票簿设置为付款”的参数)。
   _issuer必须是外部拥有的帐户,或者它必须支持调用函数cashCheque
   @param _token此支票簿使用的令牌
   @param _defaultHardDepositTimeout持续时间(以秒为单位),默认情况下将用于减少hardDeposit分配
  */
  function init(address _issuer, address _token, uint _defaultHardDepositTimeout) public {
    require(_issuer != address(0), "invalid issuer");
    require(issuer == address(0), "already initialized");
    issuer = _issuer;
    token = ERC20(_token);
    defaultHardDepositTimeout = _defaultHardDepositTimeout;
  }

  /// @return 支票簿的余额
  function balance() public view returns(uint) {
    return token.balanceOf(address(this));
  }
  /// @return 余额中没有硬存款支付的部分
  function liquidBalance() public view returns(uint) {
    return balance().sub(totalHardDeposit);
  }

  /// @return 余额中可用于特定受益人的部分
  function liquidBalanceFor(address beneficiary) public view returns(uint) {
    return liquidBalance().add(hardDeposits[beneficiary].amount);
  }
  /**
  @dev内部函数负责检查issuerSignature,更新hardDeposit余额并进行转账。
   由CashCheque和CashChequeBeneficary调用
   @param受益人支票分配给的受益人。 受益人必须是外部拥有的帐户
   @param接收者会收到累计付款与已付给受益人减去调用者的款项之间的差额
   @paramcumulativePayout分配给受益人的累计支票数量
   @param issuerSig如果发行人不是发件人,则发行人必须已在累计付款上明确授予受益人
  */
  function _cashChequeInternal(
    address beneficiary,
    address recipient,
    uint cumulativePayout,
    uint callerPayout,
    bytes memory issuerSig
  ) internal {
    /* 发行人必须通过作为主叫方或通过签名明确批准累计支付 */
    if (msg.sender != issuer) {
      require(issuer == recoverEIP712(chequeHash(address(this), beneficiary, cumulativePayout), issuerSig),
      "invalid issuer signature");
    }
    /* requestPayout是请求进行付款处理的金额 */
    uint requestPayout = cumulativePayout.sub(paidOut[beneficiary]);
    /* 计算实际支出 */
    uint totalPayout = Math.min(requestPayout, liquidBalanceFor(beneficiary));
    /* 计算硬存款使用量 */
    uint hardDepositUsage = Math.min(totalPayout, hardDeposits[beneficiary].amount);
    require(totalPayout >= callerPayout, "SimpleSwap: cannot pay caller");
    /* 如果有一些使用的硬存款,请更新hardDeposits */
    if (hardDepositUsage != 0) {
      hardDeposits[beneficiary].amount = hardDeposits[beneficiary].amount.sub(hardDepositUsage);

      totalHardDeposit = totalHardDeposit.sub(hardDepositUsage);
    }
    /* 增加存储的payedOut金额以避免双倍支付 */
    paidOut[beneficiary] = paidOut[beneficiary].add(totalPayout);
    totalPaidOut = totalPaidOut.add(totalPayout);

    /* 让全世界知道发行人对未兑现支票的承诺过高 */
    if (requestPayout != totalPayout) {
      bounced = true;
      emit ChequeBounced();
    }

    if (callerPayout != 0) {
    /* 如果指定,则转接到呼叫者 */
      require(token.transfer(msg.sender, callerPayout), "transfer failed");
      /* 进行实际付款 */
      require(token.transfer(recipient, totalPayout.sub(callerPayout)), "transfer failed");
    } else {
      /* 进行实际付款 */
      require(token.transfer(recipient, totalPayout), "transfer failed");
    }

    emit ChequeCashed(beneficiary, recipient, msg.sender, totalPayout, cumulativePayout, callerPayout);
  }
  /**
  @notice兑现非受益人的受益人支票,并通过发送方与发件人奖励这样做
  @dev受益人必须能够生成签名(作为外部拥有的帐户)才能使用此功能
  @param受益人支票分配给的受益人。受益人必须是外部拥有的帐户
  @param接收者会收到累计付款与已付给受益人减去调用者的款项之间的差额
  @paramcumulativePayout分配给受益人的累计支票数量
  @param受益人Sig受益人必须已经明确批准才能由发件人兑现累计付款并发送给callerPayout
  @param issuerSig如果发行人不是发件人,则发行人必须已在累计付款上明确授予受益人
  @param callerPayout当受益人还没有以太币时,他可以在callerPayout的帮助下激励其他人兑现支票
  @param issuerSig如果发行人不是发件人,则发行人必须已在累计付款上明确授予受益人
  */
  function cashCheque(
    address beneficiary,
    address recipient,
    uint cumulativePayout,
    bytes memory beneficiarySig,
    uint256 callerPayout,
    bytes memory issuerSig
  ) public {
    require(
      beneficiary == recoverEIP712(
        cashOutHash(
          address(this),
          msg.sender,
          cumulativePayout,
          recipient,
          callerPayout
        ), beneficiarySig
      ), "invalid beneficiary signature");
    _cashChequeInternal(beneficiary, recipient, cumulativePayout, callerPayout, issuerSig);
  }

  /**
  @注意兑现支票作为受益人
   @param接收者会收到累计付款与已付给受益人减去调用者的款项之间的差额
   @param的累计付款要求付款
   @param issuerSig发行者必须已对收款人的累计付款给予明确批准
  */
  function cashChequeBeneficiary(address recipient, uint cumulativePayout, bytes memory issuerSig) public {
    _cashChequeInternal(msg.sender, recipient, cumulativePayout, 0, issuerSig);
  }

  /**
  @注意准备减少硬沉积
   @dev减少hardDeposit必须分两步完成,以使受益人兑现任何未兑现的支票(并利用相关的硬存款)
   @param受益人,应减少其硬存款
   @param reduction存款应减少的金额
  */
  function prepareDecreaseHardDeposit(address beneficiary, uint decreaseAmount) public {
    require(msg.sender == issuer, "SimpleSwap: not issuer");
    HardDeposit storage hardDeposit = hardDeposits[beneficiary];
    /* 如果减少的幅度超过存款,则不能减少 */
    require(decreaseAmount <= hardDeposit.amount, "hard deposit not sufficient");
    // 如果从未设置hardDeposit.timeout,则应用defaultHardDepositTimeout
    uint timeout = hardDeposit.timeout == 0 ? defaultHardDepositTimeout : hardDeposit.timeout;
    hardDeposit.canBeDecreasedAt = block.timestamp + timeout;
    hardDeposit.decreaseAmount = decreaseAmount;
    emit HardDepositDecreasePrepared(beneficiary, decreaseAmount);
  }

  /**
  @notice自调用prepareDecreaseHard存款以来等待了必要的时间后,减少了硬存款
  @param受益人,应减少其硬存款
  */
  function decreaseHardDeposit(address beneficiary) public {
    HardDeposit storage hardDeposit = hardDeposits[beneficiary];
    require(block.timestamp >= hardDeposit.canBeDecreasedAt && hardDeposit.canBeDecreasedAt != 0, "deposit not yet timed out");
    /* this throws if decreaseAmount > amount */
    //TODO: 如果prepareDecreaseHardDeposit和reducedHardDeposit之间有现金兑现,那么reducingHardDeposit将抛出并且无法减少硬存款。
    hardDeposit.amount = hardDeposit.amount.sub(hardDeposit.decreaseAmount);
    /* 重置canBeDecreasedAt以避免两次减少 */
    hardDeposit.canBeDecreasedAt = 0;
    /* 保持totalDeposit同步 */
    totalHardDeposit = totalHardDeposit.sub(hardDeposit.decreaseAmount);
    emit HardDepositAmountChanged(beneficiary, hardDeposit.amount);
  }

  /**
  @注意增加硬保证金
   @param受益人,应减少其硬存款
   @param金额新的硬存款
  */
  function increaseHardDeposit(address beneficiary, uint amount) public {
    require(msg.sender == issuer, "SimpleSwap: not issuer");
    /* 确保保证金不超过全球余额 */
    require(totalHardDeposit.add(amount) <= balance(), "hard deposit exceeds balance");

    HardDeposit storage hardDeposit = hardDeposits[beneficiary];
    hardDeposit.amount = hardDeposit.amount.add(amount);
    // 我们没有明确设置hardDepositTimout,因为零意味着使用默认的HardDeposit超时
    totalHardDeposit = totalHardDeposit.add(amount);
    /* 禁用任何未决的减少 */
    hardDeposit.canBeDecreasedAt = 0;
    emit HardDepositAmountChanged(beneficiary, hardDeposit.amount);
  }

  /**
 @notice允许为每个受益人设置自定义的hardDepositDecreaseTimeout
   @dev,当必须保证偿付能力的时间长于defaultHardDepositDecreaseTimeout时,这是必需的
   @param收款人的硬存款减少的受益人必须更改超时
   @param hardDepositTimeout受益人新的hardDeposit.timeout
   @param受益人Sig受益人必须通过在新的reduceTimeout上签名来明确批准
  */
  function setCustomHardDepositTimeout(
    address beneficiary,
    uint hardDepositTimeout,
    bytes memory beneficiarySig
  ) public {
    require(msg.sender == issuer, "not issuer");
    require(
      beneficiary == recoverEIP712(customDecreaseTimeoutHash(address(this), beneficiary, hardDepositTimeout), beneficiarySig),
      "invalid beneficiary signature"
    );
    hardDeposits[beneficiary].timeout = hardDepositTimeout;
    emit HardDepositTimeoutChanged(beneficiary, hardDepositTimeout);
  }

  /// @notice提取以太币
   /// @param要提取的金额
   // solhint-disable-next-line no-simple-event-func-name
  function withdraw(uint amount) public {
    /* 只有发行人可以做到这一点 */
    require(msg.sender == issuer, "not issuer");
    /* 确保我们不从保证金中提取任何东西 */
    require(amount <= liquidBalance(), "liquidBalance not sufficient");
    require(token.transfer(issuer, amount), "transfer failed");
  }

  function chequeHash(address chequebook, address beneficiary, uint cumulativePayout)
  internal pure returns (bytes32) {
    return keccak256(abi.encode(
      CHEQUE_TYPEHASH,
      chequebook,
      beneficiary,
      cumulativePayout
    ));
  }  

  function cashOutHash(address chequebook, address sender, uint requestPayout, address recipient, uint callerPayout)
  internal pure returns (bytes32) {
    return keccak256(abi.encode(
      CASHOUT_TYPEHASH,
      chequebook,
      sender,
      requestPayout,
      recipient,
      callerPayout
    ));
  }

  function customDecreaseTimeoutHash(address chequebook, address beneficiary, uint decreaseTimeout)
  internal pure returns (bytes32) {
    return keccak256(abi.encode(
      CUSTOMDECREASETIMEOUT_TYPEHASH,
      chequebook,
      beneficiary,
      decreaseTimeout
    ));
  }
}

Cash Cheque Beneficiary

https://goerli.etherscan.io/tx/0x6e255bcd2eb2a84d2a80e25368413f805a036d3cea18d43c81e96f0158a3084c

ETH 2.0技术调研

https://ethos.dev/beacon-chain/

稍后补充

Swarm Bee 安装与测试

简介

Swarm是一种去中心化的数据存储和分发技术,可以为下一代不受审查审查的,不可阻挡的无服务器应用程序提供动力。它是最初由以太坊加密货币设想的基于区块链的智能合约的补充,并在Dapp构建难题中提供了大容量存储部分。Swarm是世界计算机的硬盘驱动器。

Bee是Swarm网络的客户端程序

Bee 安装

测试系统 Ubuntu 18.04

安装过程

  1. (推荐)为Bee设置一个外部签名者(即安装bee-clef)
  2. 安装Bee应用程序包
  3. 用gETH和gBZZ为您的节点提供资金

安装Bee clef软件包

https://docs.ethswarm.org/docs/installation/bee-clef/
https://github.com/ethersphere/bee-clef/releases

wget https://github.com/ethersphere/bee-clef/releases/download/v0.4.10/bee-clef_0.4.10_amd64.deb
sudo dpkg -i bee-clef_0.4.10_amd64.deb

配置Bee-clef

cd /etc/bee-clef/

在正常/默认软件包安装下,开始使用bee-clef不需要进行任何配置更改。

检查Bee-clef是否安装正确

一旦安装了Clef,它将开始作为服务运行。
要检查Clef是否运行正常,我们可以使用systemctl

systemctl status bee-clef
surou@bcskill:/etc/bee-clef$ systemctl status bee-clef
● bee-clef.service - Bee Clef
   Loaded: loaded (/lib/systemd/system/bee-clef.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2021-05-10 10:34:00 CST; 4min 8s ago
     Docs: https://docs.ethswarm.org
 Main PID: 22337 (bash)
    Tasks: 12 (limit: 4915)
   CGroup: /system.slice/bee-clef.service
           ├─22337 bash /usr/bin/bee-clef-service start
           ├─22364 clef --stdio-ui --keystore /var/lib/bee-clef/keystore --configdir /var/lib/bee-clef --chai
           └─22365 tee /var/lib/bee-clef/stdout

查看服务日志

sudo journalctl -f -u bee-clef.service

Bee-clef第一次启动时,您应该看到与以下内容非常相似的内容:

-- Logs begin at Thu 2021-03-18 14:51:48 CST. --
May 10 10:34:00 web204_234 bee-clef-service[22337]: Clef is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
May 10 10:34:00 web204_234 bee-clef-service[22337]: without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
May 10 10:34:00 web204_234 bee-clef-service[22337]: PURPOSE. See the GNU General Public License for more details.
May 10 10:34:00 web204_234 bee-clef-service[22337]: INFO [05-10|10:34:00.773] Using stdin/stdout as UI-channel
May 10 10:34:00 web204_234 bee-clef-service[22337]: INFO [05-10|10:34:00.919] Loaded 4byte database                    embeds=146841 locals=4 local=/etc/bee-clef/4byte.json
May 10 10:34:00 web204_234 bee-clef-service[22337]: {"jsonrpc":"2.0","id":1,"method":"ui_onInputRequired","params":[{"title":"Master Password","prompt":"Please enter the password to decrypt the master seed","isPassword":true}]}
May 10 10:34:01 web204_234 bee-clef-service[22337]: INFO [05-10|10:34:01.622] Rule engine configured                   file=/etc/bee-clef/rules.js
May 10 10:34:01 web204_234 bee-clef-service[22337]: INFO [05-10|10:34:01.622] Starting signer                          chainid=5 keystore=/var/lib/bee-clef/keystore light-kdf=true advanced=false
May 10 10:34:01 web204_234 bee-clef-service[22337]: INFO [05-10|10:34:01.623] IPC endpoint opened                      url=/var/lib/bee-clef/clef.ipc
May 10 10:34:01 web204_234 bee-clef-service[22337]: {"jsonrpc":"2.0","method":"ui_onSignerStartup","params":[{"info":{"extapi_http":"n/a","extapi_ipc":"/var/lib/bee-clef/clef.ipc","extapi_version":"6.1.0","intapi_version":"7.0.1"}}]}

可以安全地忽略此行,无需执行任何操作:

{"jsonrpc":"2.0","method":"ui_onSignerStartup","params":[{"info":{"extapi_http":"n/a","extapi_ipc":"/var/lib/bee-clef/clef.ipc","extapi_version":"6.1.0","intapi_version":"7.0.1"}}]}

一旦bee开始与bee-clef您进行交互,您应该开始看到日志消息,对于定期活动和连接的节点,它们将每隔几秒钟出现一次:

Feb 24 22:29:15 comp-name bee-clef-service[1118]: INFO [02-24|22:29:15.118] Op approved
Feb 24 22:30:17 comp-name bee-clef-service[1118]: INFO [02-24|22:30:17.371] Op approved
Feb 24 22:30:19 comp-name bee-clef-service[1118]: INFO [02-24|22:30:19.344] Op approved
...

数据位置

关键材料和其他数据存储在 /var/lib/bee-clef/
蜜蜂可以通过多种方式与养蜂人交流。如果通过软件包安装,则默认方式将使用进程间通信(IPC)文件。这是Bee-clef在启动时创建的特殊文件,Bee将使用该文件来回发送请求。Bee-clef服务运行时,您会注意到/var/lib/bee-clef/clef.ipc已创建一个文件。

bee节点地址私钥

文件默认创建在
keystore: /var/lib/bee-clef/keystore/
password: /var/lib/bee-clef/password
直接导入MetaMask即可

/var/lib/bee-clef# cat keystore/UTC--2021-05-10T02-33-58.763177852Z--10210fa0 6b4924af7ef946136295e9b209e1f
{"address":"10210572d6b4924af7ef946136295e9b209e1fa0","crypto":{"cipher":"aes-128-ctr","ciphertext":"9da4ef8e6154cb12524f7ffad36faf0d2c3665b537a4d11b3a4b7bb31e7028c0","cipherparams":{"iv":"29229b07608492ff369d4f4547c074bc"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":4096,"p":6,"r":8,"salt":"96c023aef9e8743fe404b3d1ccbc06b8e31fe0d0e56a4c35a422d17bd505faf3"},"mac":"fb6c344beb0124a0dada03ee454e6f5564604998100f44079b8157dbcf66abc8"},"id":"b92410f4-b583-4ef5-a3d8-9bf6b5f322bf","version":3

手动安装

要手动安装Clef,请首先从以太坊的Geth&Tools下载页面中检索相关的Clef二进制文件,或直接从源代码进行构建

由于Bee需要Clef自动签署许多交易,因此我们必须将Clef作为具有宽松权限和规则集的服务运行。为确保Clef仅签署来自Bee的交易,我们必须clef.ipc通过创建Bee用户并设置权限来保护文件,以便该用户只能使用ipc套接字。

另外,Clef需要Bee的支票簿交互的交易签名。

可以在Bee-clef存储库中找到自动执行初始化后权限更改(包括Clef配置)的Shell脚本clef-service,以及4byte.json事务签名文件和rules.js文件。

最后,一旦Clef运行,只需将Bee节点配置为启用Clef使用,--clef-signer-enable然后使用将Bee指向正确的ipc套接字即可--clef-signer-endpoint

安装Bee

wget https://github.com/ethersphere/bee/releases/download/v0.5.3/bee_0.5.3_amd64.deb
sudo dpkg -i bee_0.5.3_amd64.deb

SWAP区块链端点

您的Bee节点必须有权访问以太坊区块链,以便它可以交互并部署您的支票簿合同。您可以运行 自己的Goerli节点,也可以使用rpc.slock.it/goerliInfura之类的提供程序。

默认情况下,Bee希望在本地有Goerli节点http://localhost:8545
要改用提供程序,只需--swap-endpoint在您的配置文件中更改即可。

切换登录用户

由于程序目录的权限账户默认初始化为bee

surou@bcskill:/var/lib$ ll
total 176
drwxr-x---  4 bee       bee       4096 May 10 11:58 bee/
drwxr-x---  4 bee-clef  bee-clef  4096 May 10 10:34 bee-clef/

所以需要切换下登陆账户

su bee

修改swap-endpoint配置

sudo vi /etc/bee/bee.yaml
sudo systemctl restart bee
...
swap-endpoint: https://rpc.slock.it/goerli
...

查看日志

sudo journalctl --lines=100 --follow --unit bee
May 10 14:24:12 web204_234 bee[30421]: Error: chequebook init: insufficient BZZ for initial deposit
May 10 14:24:12 web204_234 systemd[1]: bee.service: Main process exited, code=exited, status=1/FAILURE
May 10 14:24:12 web204_234 systemd[1]: bee.service: Failed with result 'exit-code'.
May 10 14:24:17 web204_234 systemd[1]: bee.service: Service hold-off time over, scheduling restart.
May 10 14:24:17 web204_234 systemd[1]: bee.service: Scheduled restart job, restart counter is at 1.
May 10 14:24:17 web204_234 systemd[1]: Stopped Bee - Ethereum Swarm node.
May 10 14:24:17 web204_234 systemd[1]: Started Bee - Ethereum Swarm node.
May 10 14:24:17 web204_234 bee[30506]: Welcome to the Swarm.... Bzzz Bzzzz Bzzzz
May 10 14:24:17 web204_234 bee[30506]:                 \     /
May 10 14:24:17 web204_234 bee[30506]:             \    o ^ o    /
May 10 14:24:17 web204_234 bee[30506]:               \ (     ) /
May 10 14:24:17 web204_234 bee[30506]:    ____________(%%%%%%%)____________
May 10 14:24:17 web204_234 bee[30506]:   (     /   /  )%%%%%%%(  \   \     )
May 10 14:24:17 web204_234 bee[30506]:   (___/___/__/           \__\___\___)
May 10 14:24:17 web204_234 bee[30506]:      (     /  /(%%%%%%%)\  \     )
May 10 14:24:17 web204_234 bee[30506]:       (__/___/ (%%%%%%%) \___\__)
May 10 14:24:17 web204_234 bee[30506]:               /(       )\
May 10 14:24:17 web204_234 bee[30506]:             /   (%%%%%)   \
May 10 14:24:17 web204_234 bee[30506]:                  (%%%)
May 10 14:24:17 web204_234 bee[30506]:                    !
May 10 14:27:45 web204_234 bee[30602]: time="2021-05-10T14:27:45+08:00" level=info msg="version: 0.5.3-acbd0e2"
May 10 14:27:46 web204_234 bee[30602]: time="2021-05-10T14:27:46+08:00" level=info msg="using swarm network address through clef: fa9372fcd90e186a6a5e2d14864539df35e2c5e495ba6a75dd626fd5a738319e"
May 10 14:27:46 web204_234 bee[30602]: time="2021-05-10T14:27:46+08:00" level=info msg="swarm public key 038f72455a66a713be2e684a07f4f0444a8de458d0716151a5cfcd56aee1c92020"
May 10 14:27:46 web204_234 bee[30602]: time="2021-05-10T14:27:46+08:00" level=info msg="pss public key 02faa1c0f8fcdcbc1d816c4abf042b39ecc6b1ad533e3e7744b6d054a2b9bf794c"
May 10 14:27:46 web204_234 bee[30602]: time="2021-05-10T14:27:46+08:00" level=info msg="using ethereum address 10210572d6b4924af7ef946136295e9b209e1fa0"
May 10 14:27:46 web204_234 bee[30602]: time="2021-05-10T14:27:46+08:00" level=info msg="debug api address: 127.0.0.1:1635"
May 10 14:27:48 web204_234 bee[30602]: time="2021-05-10T14:27:48+08:00" level=info msg="using default factory address for chain id 5: f0277caffea72734853b834afc9892461ea18474"
May 10 14:27:49 web204_234 bee[30602]: time="2021-05-10T14:27:49+08:00" level=info msg="no chequebook found, deploying new one."
May 10 14:27:50 web204_234 bee[30602]: time="2021-05-10T14:27:50+08:00" level=warning msg="cannot continue until there is sufficient ETH (for Gas) and at least 10 BZZ available on 10210572d6b4924af7ef946136295e9b209e1fa0"
May 10 14:27:50 web204_234 bee[30602]: time="2021-05-10T14:27:50+08:00" level=warning msg="get your Goerli ETH and Goerli BZZ now via the bzzaar at https://bzz.ethswarm.org/?transaction=buy&amount=10&slippage=30&receiver=0x10210572d6b4924af7ef946136295e9b209e1fa0"

如果出现Error: open /var/lib/bee/statestore/LOCK: permission denied
则进入/var/lib/bee,确认下statestore的当前权限组是不是bee
如果不是则修改下

sudo chown bee.bee statestore
sudo systemctl restart bee

与Bee交互测试

curl localhost:1633

激活节点

启用了SWAP的Bee节点需要gETH和gBZZ才能开始操作。

cannot continue until there is sufficient ETH (for Gas) and at least 10 BZZ available on 10210572d6b4924af7ef946136295e9b209e1fa0

当前版本的Swarm激励措施正在以太坊Goerli测试网上运行。要获取免费的gBZZ令牌,请访问Bzzaar,然后执行以下步骤!

1. 查看Bee节点地址

sudo bee-get-addr
Please make sure there is sufficient ETH and BZZ available on the node's Ethereum address: 10210572d6b4924af7ef946136295e9b209e1fa0.

You can get both Goerli ETH and Goerli BZZ via the Bzzaar at https://bzz.ethswarm.org/?transaction=buy&amount=10&slippage=30&receiver=0x10210572d6b4924af7ef946136295e9b209e1fa0

或者通过API获取

curl -s localhost:1635/addresses | jq .ethereum

得到0x10210572d6b4924af7ef946136295e9b209e1fa0
确认下与前面Bee-clef创建的keystore中的地址一致

2. 获取gBZZ

通过上面日志可以获取到

https://bzz.ethswarm.org/?transaction=buy&amount=10&slippage=30&receiver=0x10210572d6b4924af7ef946136295e9b209e1fa0

3. 打开此连接,然后链接Metamask扩展

4. 点击下面的GET G-ETH

5. 等待Goerli ETH到达您的钱包

官方将向您连接的钱包和Bee的钱包中发送少量gETH(gETH 就是 goerli的 系统测试代币)!
这可能需要几分钟,请检查Etherscan上的水龙头地址,然后查找到您的地址的交易。
交易完成后,您可能需要重新连接钱包以查看余额增加。

也可以访问https://faucet.ethswarm.org/水龙头获取
如果上面的都不举,就用 https://faucet.goerli.mudit.blog/
还有 https://gitter.im/goerli/testnet?at=5f7f1d756e0eb84469728b8b

6. 兑换

一旦有了余额,在该gBZZ字段中至少输入10 ,您甚至可能有足够的gETH来购买更多!这是另一项区块链交易,只需几分钟即可查看Metamask,以查看交易进展如何。

7. 兑换完成

完成交易后,您的Bee节点应该是一些新鲜出炉的gBZZ的骄傲拥有者!

8. 检查节点

检查Bee节点,它现在应该开始部署您的支票簿合同。如果您的节点已停止轮询更新,则现在可能需要重新启动它。

一旦您的Bee节点完全加载了gBZZ,我们现在就可以观看日志,并观看Bee自动部署支票簿并进行初始存入的情况。

sudo journalctl --lines=100 --follow --unit bee
May 10 16:39:06 web204_234 bee[1654]: time="2021-05-10T16:39:06+08:00" level=info msg="attempting to connect to peer e4006955ac467eb48dbda60b9564f0a71a4af7cd558e4af8d58041ce2bf6b02b"
May 10 16:39:11 web204_234 bee[1654]: time="2021-05-10T16:39:11+08:00" level=warning msg="peer not reachable when attempting to connect"
May 10 16:39:11 web204_234 bee[1654]: time="2021-05-10T16:39:11+08:00" level=info msg="attempting to connect to peer ec085740961bf2248334c03e5fe4a4b65e498d6d045839e02eaf32e408f13954"
May 10 16:39:13 web204_234 bee[1654]: time="2021-05-10T16:39:13+08:00" level=warning msg="peer not reachable when attempting to connect"
May 10 16:39:13 web204_234 bee[1654]: time="2021-05-10T16:39:13+08:00" level=info msg="attempting to connect to peer f025b3ef8b07263b1b4852601d402db0a05e0e91102e2ac57e46cce36496208f"
May 10 16:39:18 web204_234 bee[1654]: time="2021-05-10T16:39:18+08:00" level=warning msg="peer not reachable when attempting to connect"
May 10 16:39:18 web204_234 bee[1654]: time="2021-05-10T16:39:18+08:00" level=info msg="attempting to connect to peer f20014da660cdda4c611535d5698414c428fe5d72c8d00294f83a98dfbc3d73c"
May 10 16:39:20 web204_234 bee[1654]: time="2021-05-10T16:39:20+08:00" level=warning msg="peer not reachable when attempting to connect"
May 10 16:39:20 web204_234 bee[1654]: time="2021-05-10T16:39:20+08:00" level=info msg="attempting to connect to peer f405e443f4c686f1434ef47c17943343bbfba8348f0f70a62e948eae6775480b"
May 10 16:39:22 web204_234 bee[1654]: time="2021-05-10T16:39:22+08:00" level=info msg="greeting \"Hello from ldeffenb's DAppNode!\" from peer: f405e443f4c686f1434ef47c17943343bbfba8348f0f70a62e948eae6775480b"
May 10 16:39:22 web204_234 bee[1654]: time="2021-05-10T16:39:22+08:00" level=warning msg="peer not reachable when attempting to connect"
May 10 16:39:22 web204_234 bee[1654]: time="2021-05-10T16:39:22+08:00" level=info msg="attempting to connect to peer f622fd3941ce417f99211f44d2acb0b62d7953a1da0b1d5eb21897a96d37b4b3"
May 10 16:39:27 web204_234 bee[1654]: time="2021-05-10T16:39:27+08:00" level=warning msg="peer not reachable when attempting to connect"
May 10 16:39:27 web204_234 bee[1654]: time="2021-05-10T16:39:27+08:00" level=info msg="attempting to connect to peer fc0ccee5d2b893a634fc443818d090d4a89df4ac9502ee4d140df4035318ef5d"

升级Bee

停止服务

sudo systemctl stop bee

安装最新包,
重新启动服务

sudo systemctl start bee

卸载Bee

sudo apt-get remove bee
sudo apt-get remove bee-clef

数据位置

Bee-clef

配置文件存储在 /etc/bee-clef/
关键材料和其他数据存储在 /var/lib/bee-clef/

Bee

配置文件存储在 /etc/bee/
状态,块和其他数据存储在 /var/lib/bee/

使用节点

调试API为您提供能够与您的蜜蜂节点进行交互,以获取有关您的节点的状态的详细信息,其中一个特权环境。
切勿将您的Debug API暴露在公共互联网上,请确保使用防火墙或绑定到localhost,如下面的示例所示。
要使用Debug API,我们必须先配置Bee使其启用,因为默认情况下它是禁用的。

bee start --debug-api-enable --debug-api-addr=localhost:1635

检查连接

curl -s http://localhost:1635/peers | jq '.peers | length'

检查网络拓扑

curl -X GET http://localhost:1635/topology | jq

API和调试API

https://docs.ethswarm.org/docs/api-reference/api-reference/

上传和下载文件

Bee提供了一种方便的方式将您的数据上传到Swarm。一旦您的数据被上传,它将被遍布全球的p2p节点网络分发和存储,并可以从Swarm的Web网关中获取。

快速上传

Bee节点运行后,将启用HTTP API与您进行交互。命令行实用程序curl是与Bee节点的API交互的好方法。
首先,让我们检查一下API是否按预期运行...

curl http://localhost:1633

返回

Ethereum Swarm Bee

运行后,可以通过files向Bee API的端点发出HTTP POST请求来上传文件。

curl -F file=@bee.jpg http://localhost:1633/files

我们还可以在Content-Type标头中传递适当的mime类型,并在name查询参数中传递文件名,以便Web浏览器和其他应用程序可以正确处理该文件。

curl --data-binary @bee.jpg  -H "Content-Type: video/jpg" "http://localhost:1633/files?name=bee.jpg"

返回

{"reference":"042d4fe94b946e2cb51196a8c136b8cc335156525bf1ad7e86356c2402291dd4"}

在Swarm中,每条数据都有一个唯一的地址,该地址是一个唯一且可复制的加密哈希摘要。如果您上载相同的文件两次,您将始终收到相同的哈希值。这使得在Swarm中处理数据变得超级安全!

如果您要上传大文件,则在处理上传到网络中时,跟踪上传状态非常有用。转至“高级用法”部分,以了解如何跟踪您的上传状态

文件与网络完全同步后,您将可以关闭计算机,其他节点将接管您的数据工作!

下载文件

将文件上传到Swarm后,可以使用简单的HTTP GET请求对其进行检索。
将哈希的最后一部分替换为对您自己的数据的引用。

curl -OJ http://localhost:1633/files/042d4fe94b946e2cb51196a8c136b8cc335156525bf1ad7e86356c2402291dd4

您甚至可以简单地导航到浏览器中的URL
http://localhost:1633/files/042d4fe94b946e2cb51196a8c136b8cc335156525bf1ad7e86356c2402291dd4

公共网关

要与尚未运行Bee节点的人共享文件,只需将链接中的主机更改为我们的公共网关之一。将链接发送给您的朋友,他们也可以下载文件!
https://gateway.ethswarm.org/files/042d4fe94b946e2cb51196a8c136b8cc335156525bf1ad7e86356c2402291dd4

上载目录

https://docs.ethswarm.org/docs/getting-started/upload-a-directory
可以使用Bee一次上传整个目录结构。

在Swarm上托管您的网站

https://docs.ethswarm.org/docs/getting-started/host-your-website-using-ens

加密存储

https://docs.ethswarm.org/docs/getting-started/store-with-encryption

高级用法

PSS消息传递

https://docs.ethswarm.org/docs/advanced/pss

跟踪上传状态

https://docs.ethswarm.org/docs/advanced/tags

坚持不懈

每个Bee节点均配置为在计算机硬盘驱动器上保留一定数量的内存,以在Swarm网络中其他节点的职责范围内存储和提供服务。一旦分配的空间已满,每个Bee节点将删除较旧的块,以便为较新的块腾出空间,因为它们是由网络上载的。

每次访问块时,它都会移回到删除队列的末尾,以便定期访问的内容在网络中保持活动状态,并且不会被节点的垃圾回收例程删除。

SWAP带宽核算

Swarm的基础是一组会计协议,这些协议已在5年的研发过程中开发并原型化。您的Beta Bee节点包含功能,使其能够跟踪与所有对等节点的带宽交换,使用生活在与EVM兼容的区块链上的智能合约来进行签发和缓存检查。目前,我们正在使用Goerli测试网进行测试。我们希望您能参与其中,帮助我们尝试这些激励措施,甚至可以赚取一些gBZZ!
https://docs.ethswarm.org/docs/advanced/swap

管理未兑现支票

https://docs.ethswarm.org/docs/advanced/swap#managing-uncashed-cheques
下载脚本

wget -O cashout.sh https://gist.githubusercontent.com/ralph-pichler/3b5ccd7a5c5cd0500e6428752b37e975/raw/b40510f1172b96c21d6d20558ca1e70d26d625c4/cashout.sh
chmod +x cashout.sh
./cashout.sh

如果运行./cashout.sh不返回任何内容,则您当前没有未兑现的支票。
兑现所有价值超过5 BZZ的支票

./cashout.sh cashout-all 5

启动测试网络

https://docs.ethswarm.org/docs/advanced/starting-a-test-network

大型节点运营商

https://docs.ethswarm.org/docs/advanced/large-node-operators

附加

显示BZZ

钱包添加合约地址:0x2ac3c1d3e24b45c6c310534bc2dd84b5ed576335

查看支票薄账户余额

curl localhost:1635/chequebook/balance | jq
{
  "totalBalance": 1e+17,
  "availableBalance": 1e+17
}

查看每个peer的余额

curl localhost:1635/balances | jq
{
  "balances": [
    {
      "peer": "fa7bdf0fec5c6a684d210b8b92a6dbe96014fa5bfe5b403037c6305d2cf5925e",
      "balance": 14000000000
    },
    ...

查看支票接收和发送数量

curl localhost:1635/settlements | jq
{
  "totalreceived": 9000000000,
  "totalsent": 0,
  "settlements": [
    {
      "peer": "e001cc63c87efde4092da8253787dae82590e6d2274716cbab6025c49a815b0f",
      "received": 9000000000,
      "sent": 0
    }
  ]
}

查看支票薄详情

curl localhost:1635/chequebook/cheque | jq
{
  "lastcheques": [
    {
      "peer": "e001cc63c87efde4092da8253787dae82590e6d2274716cbab6025c49a815b0f",
      "lastreceived": {
        "beneficiary": "0x10210572d6b4924Af7Ef946136295e9b209E1FA0",
        "chequebook": "0x01DC64508363ab83f0EC4DC34263ee804a5A38BF",
        "payout": 9000000000
      },
      "lastsent": null
    }
  ]
}

兑现(POST请求)

curl -XPOST http://localhost:1635/chequebook/cashout/e001cc63c87efde4092da8253787dae82590e6d2274716cbab6025c49a815b0f
{"transactionHash":"0xcd1f95980475213dabaab2c3934006b8810872cf460a656cd4b742f446655529"}

查看兑现状态(GET请求)

curl http://localhost:1635/chequebook/cashout/e001cc63c87efde4092da8253787dae82590e6d2274716cbab6025c49a815b0f | jq
{
  "peer": "e001cc63c87efde4092da8253787dae82590e6d2274716cbab6025c49a815b0f",
  "chequebook": "0x01dc64508363ab83f0ec4dc34263ee804a5a38bf",
  "cumulativePayout": 9000000000,
  "beneficiary": "0x10210572d6b4924af7ef946136295e9b209e1fa0",
  "transactionHash": "0xcd1f95980475213dabaab2c3934006b8810872cf460a656cd4b742f446655529",
  "result": {
    "recipient": "0x68f7ea9f3fae55e3e55fee0f0761b7df570fd212",
    "lastPayout": 9000000000,
    "bounced": false
  }
}

将token从合约提现到个人账户

curl -XPOST http://localhost:1635/chequebook/withdraw\?amount\=9000000000 | jq
{
  "transactionHash": "0x4e15f9b685af8ce20192102491f971279cd5c32ee229e97f45eaba874f18478e"
}

参考

https://docs.ethswarm.org/docs/
https://docs.ethswarm.org/api/
https://medium.com/ethereum-swarm/swarm-is-airdropping-1-000-000-bzz-bd3b706918d3
https://medium.com/ethereum-swarm/how-to-run-bee-on-a-dappnode-raspberry-pi-7b4993ff7583
https://blog.csdn.net/kk3909/article/details/116236431