什么是TaPos 全称:Transaction as Proof of Stake ,基于交易的权益证明机制。 大白话:这笔交易所基于的证明。 啥意思? 就是说,在区块链的场景当中,每一过往的笔交易都基于一个区块。因为区块链当中所有的交易都是被打包到一个个区块当中的,如果这是一笔成功的交易,那它一定是存在于某一个特定的区块当中。 另外,每一笔交易都有一个唯一的Hash,保证这笔交易的唯一性。那就破案了,这里的证明就是指:区块 。
有什么实际作用
防止有不包含区块引用的交易被重放到某个分叉上,这样能避免不是该分叉的区块被添加到该分叉。
告诉用户该块是在哪个分支上面。
这个需要事先了解切链场景,才能说明这个问题。
先说分叉:
在区块链网络当中,如果同时收到相同高度的区块就,链就会分叉,你可以理解为git提交记录,从master分支中切出一个新的分叉,会有人基于这个分叉不断的提交代码。 在区块链的角度也是一样的,如果区块高度都是 1000 和 1000',那这个时候链就会出现分叉。
在哪里用 一般在验证广播交易阶段使用。
构建交易 构建一笔交易时,会将这笔交易所需要引用的区块高度带上。 交易构建之后会被广播到对应的FullNode节点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 private void setTransaction (TransactionCapsule trx) { try { BlockId blockId = chainBaseManager.getHeadBlockId(); if ("solid" .equals(Args.getInstance().getTrxReferenceBlock())) { blockId = chainBaseManager.getSolidBlockId(); } trx.setReference(blockId.getNum(), blockId.getBytes()); long expiration = chainBaseManager.getHeadBlockTimeStamp() + Args.getInstance() .getTrxExpirationTimeInMilliseconds(); trx.setExpiration(expiration); trx.setTimestamp(); } catch (Exception e) { logger.error("Create transaction capsule failed." , e); } }
验证TaPos 接收到广播过来的交易后,会验证构建交易时记录的Tapos的区块高度,如果不是有资质的区块高度,就丢弃交易。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 void validateTapos (TransactionCapsule transactionCapsule) throws TaposException { byte [] refBlockHash = transactionCapsule.getInstance() .getRawData().getRefBlockHash().toByteArray(); byte [] refBlockNumBytes = transactionCapsule.getInstance() .getRawData().getRefBlockBytes().toByteArray(); try { byte [] blockHash = chainBaseManager.getRecentBlockStore().get(refBlockNumBytes).getData(); if (!Arrays.equals(blockHash, refBlockHash)) { String str = String.format( "Tapos failed, different block hash, %s, %s , recent block %s, " + "solid block %s head block %s" , ByteArray.toLong(refBlockNumBytes), Hex.toHexString(refBlockHash), Hex.toHexString(blockHash), chainBaseManager.getSolidBlockId().getString(), chainBaseManager.getHeadBlockId().getString()).toString(); logger.info(str); throw new TaposException(str); } } catch (ItemNotFoundException e) { String str = String .format("Tapos failed, block not found, ref block %s, %s , solid block %s head block %s" , ByteArray.toLong(refBlockNumBytes), Hex.toHexString(refBlockHash), chainBaseManager.getSolidBlockId().getString(), chainBaseManager.getHeadBlockId().getString()).toString(); logger.info(str); throw new TaposException(str); } }
总结 在去中心化的环境当中,各节点之间数据是独立的,也没有一个中心化的节点可以提供参照数据,还要保证是非切链的交易。 这样的场下,要保证刚创建的这笔交易是基于有交主链上的交易,就可以通过获取已经固化的区块,作为依据,这样就可以保证这笔交易是基于主链上的交易。