您正在查看: Ethereum-优秀转载 分类下的文章

以太坊web3j开发常用代码片段整理

获取账户的Nonce

public static BigInteger getNonce(Web3j web3j, String addr) {
 try {
     EthGetTransactionCount getNonce = web3j.ethGetTransactionCount(addr,DefaultBlockParameterName.PENDING).send();
      if (getNonce == null){
                throw new RuntimeException("net error");
            }
            return getNonce.getTransactionCount();
        } catch (IOException e) {
            throw new RuntimeException("net error");
        }
    }

获取ETH余额

public static BigDecimal getBalance(Web3j web3j, String address) {
        try {
            EthGetBalance ethGetBalance = web3j.ethGetBalance(address, DefaultBlockParameterName.LATEST).send();
            return Convert.fromWei(new BigDecimal(ethGetBalance.getBalance()),Convert.Unit.ETHER);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

获取代币余额 方法一

public static BigInteger getTokenBalance(Web3j web3j, String fromAddress, String contractAddress) {
        String methodName = "balanceOf";
        List<Type> inputParameters = new ArrayList<>();
        List<TypeReference<?>> outputParameters = new ArrayList<>();
        Address address = new Address(fromAddress);
        inputParameters.add(address);

        TypeReference<Uint256> typeReference = new TypeReference<Uint256>() {
        };
        outputParameters.add(typeReference);
        Function function = new Function(methodName, inputParameters, outputParameters);
        String data = FunctionEncoder.encode(function);
        Transaction transaction = Transaction.createEthCallTransaction(fromAddress, contractAddress, data);

        EthCall ethCall;
        BigInteger balanceValue = BigInteger.ZERO;
        try {
            ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
            List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
            balanceValue = (BigInteger) results.get(0).getValue();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return balanceValue;
    }

获取代币余额 方法二 (仅支持主链上的代币)

String tokenBanceUrl =  "https://api.etherscan.io/api?module=account&action=tokenbalance"
     + "&contractaddress=0x5aA8D6dE8CBf23DAC734E6f904B93bD056B15b81"//Token合约地址
     + "&address=0xd4279e30e27f52ca60fac3cc9670c7b9b1eeefdc"//要查询额的账户余地址
     + "&tag=latest&apikey=YourApiKeyToken";

  String result = HttpRequestUtil.sendGet(tokenBanceUrl, "");
  TokenBalanceResult tokenBalanceResult = JSON.parseObject(result, TokenBalanceResult.class);
  System.out.println(tokenBalanceResult.toString());
  if (tokenBalanceResult.getStatus() == 1) {
   BigDecimal tokenCount = new BigDecimal(tokenBalanceResult.getResult())
     .divide(new BigDecimal(10).pow(FinalValue.TOKEN_DECIMALS));
   return tokenCount.floatValue();
  }

构造交易

// 构造eth交易
Transaction transaction = Transaction.createEtherTransaction(fromAddr, nonce, gasPrice, null, toAddr, value);
// 构造合约调用交易
Transaction transaction = Transaction.createFunctionCallTransaction(fromAddr, nonce, gasPrice, null, contractAddr, funcABI);

估算手续费上限

public static BigInteger getTransactionGasLimit(Web3j web3j, Transaction transaction) {
        try {
            EthEstimateGas ethEstimateGas = web3j.ethEstimateGas(transaction).send();
            if (ethEstimateGas.hasError()){
                throw new RuntimeException(ethEstimateGas.getError().getMessage());
            }
            return ethEstimateGas.getAmountUsed();
        } catch (IOException e) {
            throw new RuntimeException("net error");
        }
    }

转账ETH

public static String transferETH(Web3j web3j, String fromAddr, String privateKey, String toAddr, BigDecimal amount, String data){
        // 获得nonce
        BigInteger nonce = getNonce(web3j, fromAddr);
        // value 转换
        BigInteger value = Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger();

        // 构建交易
        Transaction transaction = Transaction.createEtherTransaction(fromAddr, nonce, gasPrice, null, toAddr, value);
        // 计算gasLimit
        BigInteger gasLimit = getTransactionGasLimit(web3j, transaction);

        // 查询调用者余额,检测余额是否充足
        BigDecimal ethBalance = getBalance(web3j, fromAddr);
        BigDecimal balance = Convert.toWei(ethBalance, Convert.Unit.ETHER);
        // balance < amount + gasLimit ??
        if (balance.compareTo(amount.add(new BigDecimal(gasLimit.toString()))) < 0) {
            throw new RuntimeException("余额不足,请核实");
        }

        return signAndSend(web3j, nonce, gasPrice, gasLimit, toAddr, value, data, chainId, privateKey);
    }

转账代币

public static String transferToken(Web3j web3j, String fromAddr, String privateKey, String toAddr, String contractAddr, long amount) {

        BigInteger nonce = getNonce(web3j, fromAddr);
        // 构建方法调用信息
        String method = "transfer";

        // 构建输入参数
        List<Type> inputArgs = new ArrayList<>();
        inputArgs.add(new Address(toAddr));
        inputArgs.add(new Uint256(BigDecimal.valueOf(amount).multiply(BigDecimal.TEN.pow(18)).toBigInteger()));

        // 合约返回值容器
        List<TypeReference<?>> outputArgs = new ArrayList<>();

        String funcABI = FunctionEncoder.encode(new Function(method, inputArgs, outputArgs));

        Transaction transaction = Transaction.createFunctionCallTransaction(fromAddr, nonce, gasPrice, null, contractAddr, funcABI);
        RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, null, contractAddr, null, funcABI);

        BigInteger gasLimit = getTransactionGasLimit(web3j, transaction);

        // 获得余额
        BigDecimal ethBalance = getBalance(web3j, fromAddr);
        BigInteger tokenBalance = getTokenBalance(web3j, fromAddr, contractAddr);
        BigInteger balance = Convert.toWei(ethBalance, Convert.Unit.ETHER).toBigInteger();

        if (balance.compareTo(gasLimit) < 0) {
            throw new RuntimeException("手续费不足,请核实");
        }
        if (tokenBalance.compareTo(BigDecimal.valueOf(amount).toBigInteger()) < 0) {
            throw new RuntimeException("代币不足,请核实");
        }

        return signAndSend(web3j, nonce, gasPrice, gasLimit, contractAddr, BigInteger.ZERO, funcABI, chainId, privateKey);
    }

转账代币方法二

public static String transferToken2(String fromAddr,String toAddr,String amount) {
  String contractAddress = "0xa22c2217e785f7796c9e8826c6be55c2e481f9f5";
  Web3j web3j =MyWalletUtils.getWeb3j();
     Credentials credentials = MyWalletUtils.getCredentials();
     System.out.println("我的钱包地址:"+credentials.getAddress());
  try {
   EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(
     fromAddr, DefaultBlockParameterName.LATEST).sendAsync().get();
     BigInteger nonce = ethGetTransactionCount.getTransactionCount();
     Function function = new Function(
             "transfer",
             Arrays.asList(new Address(toAddr), new Uint256(new BigInteger(amount))), 
             Arrays.asList(new TypeReference<Type>() {
             }));
     String encodedFunction = FunctionEncoder.encode(function);
     RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, Convert.toWei("18", Convert.Unit.GWEI).toBigInteger(),
             Convert.toWei("100000", Convert.Unit.WEI).toBigInteger(), contractAddress, encodedFunction);
     byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
     String hexValue = Numeric.toHexString(signedMessage);
     System.out.println("transfer hexValue:" + hexValue);
     EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).sendAsync().get();
     if (ethSendTransaction.hasError()) {
      System.out.println("transfer error:"+ ethSendTransaction.getError().getMessage());
      return ethSendTransaction.getError().getMessage();
     } else {
         String transactionHash = ethSendTransaction.getTransactionHash();
        return "";
     }
  } catch (Exception e) {
   e.printStackTrace();
   return e.getMessage();
  }
 }

对交易签名,并发送交易

public static String signAndSend(Web3j web3j, BigInteger nonce, BigInteger gasPrice, BigInteger gasLimit, String to, BigInteger value, String data, byte chainId, String privateKey) {
        String txHash = "";
        RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, gasPrice, gasLimit, to, value, data);
        if (privateKey.startsWith("0x")){
            privateKey = privateKey.substring(2);
        }

        ECKeyPair ecKeyPair = ECKeyPair.create(new BigInteger(privateKey, 16));
        Credentials credentials = Credentials.create(ecKeyPair);

        byte[] signMessage;
        // 主网是1 responst测试网是3  具体查看ChainId
        if (chainId > ChainId.NONE){
            signMessage = TransactionEncoder.signMessage(rawTransaction, chainId, credentials);
        } else {
            signMessage = TransactionEncoder.signMessage(rawTransaction, credentials);
        }

        String signData = Numeric.toHexString(signMessage);
        if (!"".equals(signData)) {
            try {
                EthSendTransaction send = web3j.ethSendRawTransaction(signData).send();
                txHash = send.getTransactionHash();
                System.out.println(JSON.toJSONString(send));
            } catch (IOException e) {
                throw new RuntimeException("交易异常");
            }
        }
        return txHash;
    }

获取代理额度

public static BigInteger getAllowanceBalance(Web3j web3j, String fromAddr, String toAddr, String contractAddress) {
        String methodName = "allowance";
        List<Type> inputParameters = new ArrayList<>();
        inputParameters.add(new Address(fromAddr));
        inputParameters.add(new Address(toAddr));

        List<TypeReference<?>> outputs = new ArrayList<>();
        TypeReference<Uint256> typeReference = new TypeReference<Uint256>() {
        };
        outputs.add(typeReference);

        Function function = new Function(methodName, inputParameters, outputs);
        String data = FunctionEncoder.encode(function);
        Transaction transaction = Transaction.createEthCallTransaction(fromAddr, contractAddress, data);
        EthCall ethCall;
        BigInteger balanceValue = BigInteger.ZERO;
        try {
            ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).send();
            List<Type> result = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
            balanceValue = (BigInteger) result.get(0).getValue();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return balanceValue;
    }

动态gas价格与限价

在使用智能合约时,你可能需要根据调用函数指定不同的gas价格和最大值。你可以通过为智能合约封装包创建自己的ContractGasProvider来实现这一点。

每一个生成的封装包都包含作为常量的所有智能合约方法名称,这有助于通过switch来进行编译时间匹配。

例如,使用Greeter合约:

Greeter greeter = new Greeter(...);
greeter.setGasProvider(new DefaultGasProvider() {
    @Override
    public BigInteger getGasPrice(String contractFunc) {
        switch (contractFunc) {
            case Greeter.FUNC_GREET: return BigInteger.valueOf(22_000_000_000L);
            case Greeter.FUNC_KILL: return BigInteger.valueOf(44_000_000_000L);
            default: throw new NotImplementedException();
        }
    }

    @Override
    public BigInteger getGasLimit(String contractFunc) {
        switch (contractFunc) {
            case Greeter.FUNC_GREET: return BigInteger.valueOf(4_300_000);
            case Greeter.FUNC_KILL: return BigInteger.valueOf(5_300_000);
            default: throw new NotImplementedException();
        }
    }
});

如何加快以太坊交易确认被打包的的速度---gasprice

https://ethgasstation.info/json/ethgasAPI.json

结果

{
    "average":25, //平均值(Gwei*10的结果)
    "fastestWait":0.5,
    "fastWait":0.7,
    "fast":36,  //最快(Gwei*10的结果)
    "safeLowWait":1.2,
    "blockNum":6274955,
    "avgWait":1.2,
    "block_time":13.876288659793815,
    "speed":0.9481897143119544,
    "fastest":330,
    "safeLow":25    //安全最低值(Gwei*10的结果)
}
发送交易平均正常速度被打包gasprice,单位是wei
var average_gasprice_wei = average*10e8;
发送交易超快被打包的gasprice,单位是wei
var fast_gasprice_wei = fast*10e8;
发送交易最慢被打包的gasprice,单位是wei
var safeLow_gasprice_wei = safeLow*10e8;

转载自:https://www.jianshu.com/p/a63b0c86924d

Swarm节点出票版本选择

目前0.5.3的节点还能接收到一些测试的支票,得到的支票还能参与空投么?

您可能会在 0.5.3 中获得支票,但自 6 月 1 日官方 0.6.2 更新公告以来,它们将不符合空投资格。
https://discord.com/channels/799027393297514537/810905662375854123/851855211835424768

为什么我看到很多特别组织的都声称已经接收了大量0.6.2版本的支票了

Actually, yes, someone or someones are attempting to cheat by cascading ever-increasing check values across checkbooks that they control. What they don't realize is that this is futile as NONE of the checks issued by non-trusted (read: our) nodes will ever convert to qBZZ because the queen bee nodes will be selected from "trusted" nodes, which to me means nodes that are run by the core swarm team.

实际上,是的,某人或某人正试图通过在他们控制的支票簿中级联不断增加的支票值来作弊。 他们没有意识到这是徒劳的,因为不受信任(阅读:我们的)节点发出的检查都不会转换为 qBZZ,因为蜂王节点将从“受信任”节点中选择,这对我来说意味着 由核心swarm 团队运行的节点

https://discord.com/channels/799027393297514537/810905662375854123/851842182747127818
https://discord.com/channels/799027393297514537/810905662375854123/851843762082283541

IBFT共识概述

介绍

伊斯坦布尔拜占庭容错(IBFT)共识是受Castro-Liskov 99论文启发的。

了iBFT通过使用3相一致,从原来PBFT继承PRE-PREPARE,PREPARE和COMMIT。系统最多可以容忍验证器网络中的F故障节点N,其中N = 3F + 1。

执行

术语

  • Validator:阻止验证参与者。
  • Proposer:区块验证参与者,被选择在共识回合中提议区块。
  • Round:共识轮。一轮以提议者创建整体提议开始,以整体承诺或轮次更改结束。
  • Proposal:正在进行共识处理的新区块生成提案。
  • Sequence:投标的序号。序列号应大于所有先前的序列号。当前,每个建议的块高度是其关联的序列号。
  • Backlog:用于保存将来的共识消息的存储。
  • Round state:特定顺序和回合的共识消息,包括预准备消息,准备消息和提交消息。
  • Consensus proof:可以证明该区块已通过共识过程的区块的承诺签名。
  • Snapshot:验证者从上一个时期开始的投票状态。

共识

《伊斯坦布尔BFT共识协议》从回合开始,0验证者以循环方式从他们自己选择提议者。然后,提议者将提出一个新的整体提议,并将其与PRE-PREPARE消息一起广播。在收到PRE-PREPARE来自提议者的消息后,其他验证者将验证传入的提议并输入消息的状态PRE-PREPARED并广播PREPARE消息。此步骤是确保所有验证程序都在相同的序列和同一轮上工作。当验证器从其他验证器接收到ceil(2N/3)ofPREPARE消息时,验证器将切换到的状态PREPARED并进行广播COMMIT信息。此步骤是要通知其他验证者它接受建议的块,并将该块插入到链中。最后,验证等待ceil(2N/3)的COMMIT消息进入COMMITTED状态,再追加块链。

Istanbul BFT协议中的块是最终的,这意味着没有分叉,并且任何有效块都必须位于主链中的某个位置。为了防止故障节点生成与主链完全不同的链,每个验证器都会在将ceil(2N/3)接收到的COMMIT签名extraData插入到链中之前,将接收到的签名附加到标头中的字段。因此,所有块都是可自我验证的。但是,动态extraData会导致块哈希计算出现问题。由于来自不同验证器的同一块可以具有不同的COMMIT签名集,因此同一块也可以具有不同的块哈希。为了解决这个问题,我们通过排除COMMIT签名部分来计算块哈希。因此,我们仍然可以保持块/块哈希的一致性,并在块头中放入共识证明。

共识国家

Istanbul BFT是一种状态机复制算法。每个验证器维护一个状态机副本,以便达成块共识。IBFT共识中的各个州是,

  • NEW ROUND:提案人发送新的整体提案。验证程序等待PRE-PREPARE消息。
  • PRE-PREPARED:验证者已收到PRE-PREPARE消息并广播PREPARE消息。然后,它等待ceil(2N/3)的PREPARE或COMMIT消息。
  • PREPARED:验证器接收到ceil(2N/3)的PREPARE消息和广播COMMIT消息。然后,它等待ceil(2N/3)的COMMIT消息。
  • COMMITTED:验证器接收到ceil(2N/3)的COMMIT消息,并且能够将提出块插入blockchain。
  • FINAL COMMITTED:将一个新块成功插入到区块链中,并且验证器已准备好进行下一轮。
  • ROUND CHANGE:一个验证正在等待ceil(2N/3)的ROUND CHANGE同一提出全面数量的消息。
状态转换

  • NEW ROUND-> PRE-PREPARED:
    • 投标人从收集交易txpool。
    • 提议者生成一个整体提议并将其广播给验证者。然后进入PRE-PREPARED状态。
    • 每个验证器PRE-PREPARED在收到PRE-PREPARE具有以下条件的消息时都会进入:
      • 整体提案来自有效的提案者。
      • 块头有效。
      • 阻止提议的顺序和回合匹配验证者的状态。
    • 验证者将PREPARE消息广播到其他验证者。
  • PRE-PREPARED-> PREPARED:
    • 验证器接收ceil(2N/3)到有效PREPARE消息以进入PREPARED状态。有效消息符合以下条件:
      • 匹配顺序和舍入。
      • 匹配的块哈希。
      • 消息来自已知的验证器。
    • 验证器COMMIT在进入PREPARED状态时广播消息。
  • PREPARED-> COMMITTED:
    • 验证器接收ceil(2N/3)到有效COMMIT消息以进入COMMITTED状态。有效消息符合以下条件:
      • 匹配顺序和舍入。
      • 匹配的块哈希。
      • 消息来自已知的验证器。
  • COMMITTED-> FINAL COMMITTED:
    • 验证程序将ceil(2N/3)承诺签名附加到extraData并尝试将块插入到区块链中。
    • FINAL COMMITTED插入成功后,验证器进入状态。
  • FINAL COMMITTED-> NEW ROUND:
    • 验证者选择一个新的提议者,并开始一个新的回合计时器。
回合变更流程
  • 可以触发ROUND CHANGE以下三个条件:
    • 轮换计时器到期。
    • 无效的PREPREPARE讯息。
    • 块插入失败。
  • 当验证者注意到上述条件之一适用时,它将广播ROUND CHANGE消息以及建议的轮回编号,并等待ROUND CHANGE来自其他验证者的消息。根据以下条件选择建议的轮数:
    • 如果验证已收到ROUND CHANGE来自同行的消息,它选择具有最大回合数F + 1的ROUND CHANGE消息。
    • 否则,它将选择1 + current round number为建议的轮数。
  • 验证器每当收到相同提议轮数上的消息时,就会将接收F + 1到的ROUND CHANGE消息与自己的消息进行比较。如果接收到的ROUND CHANGE消息更大,则验证器将使用接收到的号码再次广播消息。
  • 当接收ceil(2N/3)的ROUND CHANGE在同提出的圆数量的消息,所述验证器退出轮变化循环,计算出新的提议,然后进入NEW ROUND状态。
  • 验证器跳出舍入循环的另一个条件是它通过对等同步接收到已验证的块。
提案人选择

目前,我们支持两种政策:轮循和粘性提议者。

  • 轮询:轮询是默认的提议者选择策略。在此设置中,提议者将在每个区块和每个回合中更改。
  • 粘性提议者:在粘性提议者设置中,仅在发生回合更改时提议者才会更改。
验证人名单投票

Istanbul BFT使用与Clique类似的验证者投票机制,并从Clique EIP复制大部分内容。每个时代的交易都会重置验证者投票,这意味着将添加或删除验证者的所有待处理投票都将重置。

对于所有交易块:

  • 提议者可以投一票以提议更改验证者列表。
  • 每个目标受益人的最新提议仅由单个验证者保存。
  • 随着链条的进行,将实时计票(允许并发提案)。
  • 达成多数共识的提案VALIDATOR_LIMIT立即生效。
  • 无效的建议书不会因为客户实施的简化而受到惩罚。
  • 提案生效后,必须放弃该提案的所有未决票(赞成和反对)。
未来的消息和积压

在异步网络环境中,可能会收到将来无法在当前状态下处理的消息。例如,验证程序可以COMMIT在上接收消息NEW ROUND。我们称这种消息为“未来消息”。当验证器收到将来的消息时,它将把消息放入待办事项中,并尝试在以后尽可能的处理。

常数

Istanbul BFT定义以下常量

  • EPOCH_LENGTH:默认:30000个块。检查点并重置未决投票的块数。
  • REQUEST_TIMEOUT:在以毫秒为单位触发一轮变更之前,每个共识轮都超时。
  • BLOCK_PERIOD:两个连续块之间的最小时间戳差异(以秒为单位)。
  • PROPOSER_POLICY:投标者选择策略,默认为轮询。
  • ISTANBUL_DIGEST:固定幻数0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365的mixDigest在伊斯坦布尔块识别块标题。
  • DEFAULT_DIFFICULTY:默认阻止难度,设置为0x0000000000000001。
  • EXTRA_VANITY:为提议者虚荣保留的固定数量的额外数据前缀字节。
    • 建议的32字节数,以保留当前的额外数据余量。
  • NONCE_AUTH:不可思议的随机数0xffffffffffffffff,可在添加验证器时进行投票。
  • NONCE_DROP:不可思议的随机数,0x0000000000000000用于对删除验证程序进行投票。
  • UNCLE_HASH:总是Keccak256(RLP([]))像叔叔在PoW之外毫无意义。
  • PREPREPARE_MSG_CODE:固定号码0。消息的消息代码PREPREPARE。
  • PREPARE_MSG_CODE:固定号码1。消息的消息代码PREPARE。
  • COMMIT_MSG_CODE:固定号码2。消息的消息代码COMMIT。
  • ROUND_CHANGE_MSG_CODE:固定号码3。用于消息的代码ROUND CHANGE的消息
  • VALIDATOR_LIMIT:通过授权或取消授权提议的验证者数量。
    • 必须floor(N / 2) + 1在链上执行多数共识。
块头

Istanbul BFT不会添加新的块标题字段。相反,它遵循Clique重新使用ethash标头字段的方式,如下所示:

  • nonce:有关受益人字段定义的帐户的提案人提案。

    • 应NONCE_DROP提议取消授权受益人为现有验证人。
    • 应该是NONCE_AUTH提议授权受益人为新的验证人。
    • 必须用零填充,NONCE_DROP或NONCE_AUTH
  • mixHash:固定0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365用于识别伊斯坦布尔街区的魔幻数字。

  • ommersHash:必须如此,UNCLE_HASH因为叔叔在PoW之外毫无意义。

  • timestamp:必须至少是父时间戳+ BLOCK_PERIOD

  • difficulty:必须填充0x0000000000000001。

  • extraData:签名人虚荣和RLP编码的Istanbul额外数据的组合字段,其中Istanbul额外数据包含验证者列表,提议者印章和提交印章。伊斯坦布尔的额外数据定义如下:

    type IstanbulExtra struct {
          Validators    []common.Address  //Validator addresses
          Seal          []byte            //Proposer seal 65 bytes
          CommittedSeal [][]byte          //Committed seal, 65 * len(Validators) bytes
    }

    因此,extraData形式为EXTRA_VANITY | ISTANBUL_EXTRAwhere|代表固定索引,以分隔虚荣和伊斯坦布尔额外数据(不是分隔符的实际字符)。

  • 前EXTRA_VANITY字节(固定)可以包含任意提议者虚荣数据。

  • ISTANBUL_EXTRA字节是根据所计算的RLP编码的Istanbul额外数据RLP(IstanbulExtra),其中RLP()RLP编码函数IstanbulExtra是Istanbul的额外数据。

    • Validators:验证者列表,必须按升序排列。
    • Seal:标头的提议者签名盖章。
    • CommittedSeal:承诺签名盖章清单作为共识证明。

散列哈希,提议者印章和承诺印章
ethash由于以下原因,Istanbul区块哈希计算与区块哈希计算有所不同:

  1. 提议者需要盖上提议者的印章,extraData以证明该区块已被选定的提议者签名。
  2. 验证者需要放入ceil(2N/3)已提交的印章作为共识证明,extraData以证明该区块已通过共识。

ethash除了需要处理之外,该计算仍然类似于块哈希计算extraData。我们计算字段如下:

投标人印章计算

到提议者印章计算时,提交的印章仍然是未知的,因此我们计算出那些未知数为空的印章。计算如下:

  • Proposer seal: SignECDSA(Keccak256(RLP(Header)), PrivateKey)
  • PrivateKey:提议者的私钥。
  • Header:与ethash标头相同,只是不同而已extraData。
  • extraData:vanity | RLP(IstanbulExtra),其中在IstanbulExtra,CommittedSeal并且Seal是空的阵列。
区块哈希计算

在计算块哈希时,我们需要排除提交的密封,因为该数据在不同的验证器之间是动态的。因此,我们CommittedSeal在计算哈希值时会创建一个空数组。计算公式为:

  • Header:与ethash标头相同,只是不同而已extraData。
  • extraData:vanity | RLP(IstanbulExtra),其中在IstanbulExtra,CommittedSeal是一个空数组。
共识证明

在将区块插入区块链之前,每个验证者都需要ceil(2N/3)从其他验证者那里收集已提交的印章,以构成共识证明。一旦接收到足够的承诺密封,这将填补CommittedSeal中IstanbulExtra,重新计算extraData,然后再插入块成blockchain。请注意,由于提交的密封可能因不同的来源而有所不同,因此如上一节所述,我们在计算块哈希值时会排除该部分。

承诺印章计算:

提交的印章是由每个验证者对哈希值COMMIT_MSG_CODE及其私钥的消息代码签名而计算的。计算如下:

  • Committed seal:SignECDSA(Keccak256(CONCAT(Hash, COMMIT_MSG_CODE)), PrivateKey)。
  • CONCAT(Hash, COMMIT_MSG_CODE):连接块哈希和COMMIT_MSG_CODE字节。
  • PrivateKey:签署验证者的私钥。

出处

GoQuorum中的Istanbul BFT实施基于EIP 650。自从打开EIP以来,它已进行了更新,以通过引入锁定来解决安全问题。

原文:https://docs.goquorum.consensys.net/en/stable/Concepts/Consensus/IBFT/

开源以太坊浏览器

1.blockscout

开源地址:https://github.com/poanetwork/blockscout

BlockScout是一个Elixir应用程序,允许用户搜索交易,查看帐户和余额,并验证整个以太坊网络上的智能合约,包括所有的叉子和侧链。

目前可用的块探测器(即Etherscan和Etherchain)是封闭系统,不能独立验证。随着以太坊侧链在私人和公共场合的不断扩散,需要透明的工具来分析和验证交易。

2.EthVM

开源地址:https://github.com/EthVM/EthVM

EthVM是一个开源的区块链浏览器,主要关注以太坊(虽然其他网络将受到支持)在MIT许可下,并以不同语言(即TypeScript,Kotlin和Solidity)的混合编写。

您可以使用EthVM作为工具来探索自定义专用网络或现有公用网络,或者作为ETL(提取,转换,加载)平台来对数据执行不同的分析。

3.etherparty/explorer

开源地址:https://github.com/etherparty/explorer

轻盈的以太坊块探险家

4.carsenk/explorer

开源地址:https://github.com/carsenk/explorer

以太坊Block Explorer基于etherparty/explorer

5.etherchain-light

开源地址:https://github.com/gobitfly/etherchain-light

Etherchain Light是一个使用NodeJS,Express和Parity构建的以太坊区块链资源管理器。它不需要外部数据库,并从后端以太坊节点即时检索所有信息。

6.toy-block-explorer

开源地址:https://github.com/curvegrid/toy-block-explorer

用Go编写的区块链资源管理器,用于了解如何构建与以太坊区块链一起使用的服务器端应用程序。

7.mini-eth-browser

开源地址:https://github.com/ismaelbej/mini-eth-browser

一个简单的以太坊块和事务探索器。由于它不使用数据库,因此某些操作很慢。

8.eth-explorer

开源地址:https://github.com/ethnamed/eth-explorer

简单的Nodejs以太坊资源管理器

9.Clixplorer

开源地址:https://github.com/Magicking/Clixplorer

10.ethereumproject / explorer

开源地址:https://github.com/ethereumproject/explorer

11. 模仿etherscan

https://github.com/bing-chou/etherscan-explorer

参考

https://www.cnblogs.com/huangenai/p/10075876.html

以太坊生态系统资源

生态系统资源

有关用于学习和理解以太坊生态系统的可用dapp,服务,著作和知识库的指南。

该资源旨在专注于生态系统的发展,但该相关资料还包括:

欢迎捐款!

可以随意拉取并提交请求,补充您想要添加(或删除!)的工具。如果添加新工具,请添加您认为新开发人员会理解的简短描述。

感谢众多贡献者包括@corbpage和@pakaplace为Meridio做出的贡献,并感谢@jpantunes以更合理的方式重组清单列表。

资源

钱包

网络钱包

  • MyEtherWallet -用于轻松,安全地与区块链进行交互的开源工具
  • MyCrypto - 用于生成以太币钱包,处理ERC-20代币以及更轻松地与区块链进行交互工具
  • Arkane - 基于Web的钱包专注于用户友好UX和DAPP整合。(适用于移动设备)
  • Torus - 开源客户端钱包重点放在UX
  • Portis -基于Web的钱包的植入,方便用户对你的DAPP
  • Eth lightwallet - 适用于Node和浏览器的轻量级JS钱包
  • SpankCard - 浏览器内以太坊钱包,支持支付渠道
  • Mnemonic generator - 生成单词助记符和相关的公用/专用密钥对。选择“以太坊”作为硬币以生成以太坊地址。对于truffle-hd-wallet钱包很有用。

手机钱包

  • Coinbase Wallet - 移动Dapp资源管理器和 钱包
  • Cipher - 移动Dapp资源管理器
  • Trust - 用于ERC代币的 移动钱包
  • Status - 适用于以太坊的免费开源移动操作系统
  • imToken - 功能丰富的数字资产移动钱包,支持多链资产管理,DApp浏览以及安全的私有价值交换
  • Jaxx - 手机和台式机钱包。集成了Shapeshift支持
  • WallETH - 原生Android以太坊钱包
  • eth-wallet-light - 针对移动设备进行了优化的轻量级JS钱包
  • Metamask - 带有ERC令牌的Mobile Ether钱包支持beta
  • WiniWallet - 具有多个DeFi投资的DAI稳定币钱包

硬件钱包

  • Trezor - 原始硬件钱包
  • Ledger - 支持多种加密货币和代币
  • KeepKey - 简单的硬件钱包

区块浏览器

  • Etherscan - 最受欢迎的集中式查看Eth交易和合同代码的方式
  • BlockScout - 由Ethprize资助,由POA开发的开源以太坊区块浏览器
  • TrueBlocks -TrueBlocks是软件库,应用程序,工具和示例的集合,可让您更快地检索以太坊区块链数据,(b)具有较高的信息内容,(c)以完全去中心化的方式,(d) (e)以高度免维护的方式。)
  • Etherchain lite - 您的私人以太坊链的轻量级区块链浏览器
  • EthStats - 以太坊区块链分析平台
  • Scout - 以太坊上智能合约的活动和事件日志的实时数据馈送
  • ethq - 为开发人员构建的,由dfuse 驱动的,最详细的块浏览器

汽油价格计算器和工具

  • EthGasStation - 用于估算交易价格与时间的网站
  • Petrometer - 汇总从指定以太坊地址发送的所有交易的每日和总汽油消耗

服务

  • Provable - 用于智能合约的具有真实性证明的区块链Oracle服务
  • Infura - API网关,因此您不必托管自己的ETH节点
  • Quiknode - 提升个人Parity/Geth节点的服务
  • Nodesmith - 免费API访问完整的以太坊主网和testnet节点,可以像本地节点一样使用
  • dfuse - Slick区块链API构建世界一流的应用程序
  • Regis - 数字资产注册表框架
  • Treum - 如果用例面向业务流程(以前是Viant),只需考虑将Treum用作后端
  • uPort - 整体身份解决方案
  • Ether Address Lookup - Chrome扩展程序,用于网络钓鱼防护和Eth地址突出显示
  • Netstats - 以太坊网络统计
  • ENS - ENS提供了一种安全且分散的方式,可以使用简单易读的名称来处理区块链上和下的资源
  • Name Bazaar - 通过以太坊名称服务注册的名称交换的对等市场
  • Quantstamp - 一种服务,提供收费的自动和手动智能合约安全性审核
  • SmartCheck - 对Solidity源代码进行静态分析以获取安全漏洞和最佳实践
  • MD4 Online Hash Function - 使用各种哈希算法选项对输入进行哈希的工具
  • iExec SDK - 使智能合约能够脱链执行功能或应用程序。支持作为Docker映像提供的所有旧版应用程序。
  • Incentivai - 通过使用ML代理进行仿真来测试智能合约经济性
  • Arkane - A wallet provider for Dapps - 提供API网关,并为Dapps及其用户提供钱包和钱包管理。
  • Aave SDK - JavaScript库,可与作为分散贷款市场ETHLend的Aave生态系统的API连接。
  • Rockside Cloud - 以太坊网络访问提供商和财团区块链构建商
  • Chainstack - 共享和专用的以太坊节点即服务
  • BUIDLHub - 在传统的Web服务和以太坊之间创建自动化的工作流。支持bot,webhooks,自定义dapp集成等。

知识/教育

安全最佳实践

Solidity 游戏!

Scaling

参考

治理

  • Ethresear.ch - 参与以太坊研究工作的半公开论坛,包括但不限于:Casper,Sharding,EVM改进,加密经济学,等离子和状态通道
  • Fellowship of Ethereum Magicians - 该讨论区促进整个以太坊社区中个人之间的有意义的交流
  • EIPs - 的复仇改进建议库
  • Aragon Research Forum - 与Aragon研究工作相关的长篇讨论,包括治理,经济学和令牌工程

去中心化交易所

安全分散数据协议

  • Stow - 在我们的组件和SDK分钟您的用户安全地存储和共享数据。前身为Linnia。

激励/货币化工具

  • Gitcoin - 资助开源或寻找开源工作的赏金网络
  • CodeFund - 开源广告平台

很棒的清单

去中心化金融(DeFi)

  • ETHLend - 分散的点对点借贷市场,使世界各地的人们都能获得贷款或成为贷方。
  • Aave Pay - Aave Pay允许用户使用其加密货币以FIAT货币向银行帐户支付。
  • rTrees - 一种无损捐赠应用程序,用于使用DeFi兴趣来种植真实的树木。

转载:https://github.com/ConsenSys/ethereum-developer-tools-list