8 简化版支付确认（Simplified Payment Verification Privacy）

原文与翻译

It is possible to verify payments without running a full network node. A user only needs to keep a copy of the block headers of the longest proof-of-work chain, which he can get by querying network nodes until he's convinced he has the longest chain, and obtain the Merkle branch linking the transaction to the block it's timestamped in. He can't check the transaction for himself, but by linking it to a place in the chain, he can see that a network node has accepted it, and blocks added after it further confirm the network has accepted it.

As such, the verification is reliable as long as honest nodes control the network, but is more vulnerable if the network is overpowered by an attacker. While network nodes can verify transactions for themselves, the simplified method can be fooled by an attacker's fabricated transactions for as long as the attacker can continue to overpower the network. One strategy to protect against this would be to accept alerts from network nodes when they detect an invalid block, prompting the user's software to download the full block and alerted transactions to confirm the inconsistency. Businesses that receive frequent payments will probably still want to run their own nodes for more independent security and quicker verification.

轻量节点和全节点的关系

SPV 节点是这样工作的：

1. 根据钱包里的地址，把地址创建以前的区块头全部下载下来；
2. 对于之后的区块，则由全节点提供我们关心的交易（比如发送到我们钱包地址的交易）以及这个交易在某个区块的证明；
3. 关心的交易被记入区块后又有若干个新的区块头，则确信交易已经被确认。

实践 Merkle Tree 交易验证

【Python 知识点】 点击链接跳转至《自学是门手艺》相应知识点

import import_ipynb
from IPython.display import display, Markdown
import hashlib,json
import others.merkle_tree as mk_tree
display(Markdown("**First Example - Even number of transaction Merkel Tree**"))
display(Markdown('**Final root of the tree:** \n\n' + mk_tree.Jae_Tree.get_root_leaf()))
display(Markdown("**merkle tree:** \n\n" + json.dumps(mk_tree.past_transaction, indent=4)))
## =====================
display(Markdown("**verify tx by merkle tree:**"))
def verify_tx_by_merkle_tree(tx, leafs, root):
current = tx
for leaf in leafs:
current = hashlib.sha256((current + leaf).encode()).hexdigest()
return current==root
tx = "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
tx_2 = "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bd"
leafs = ["3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d", "d3a0f1c792ccf7f1708d5422696263e35755a86917ea76ef9242bd4a8cf4891a"]
root = "58c89d709329eb37285837b042ab6ff72c7c8f74de0446b091b6a0131c102cfd"

print("tx 1: " + str(verify_tx_by_merkle_tree(tx, leafs, root)))
print("tx 2: " + str(verify_tx_by_merkle_tree(tx_2, leafs, root)))


First Example - Even number of transaction Merkel Tree

Final root of the tree:

58c89d709329eb37285837b042ab6ff72c7c8f74de0446b091b6a0131c102cfd

merkle tree:

{ "a": "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", "b": "3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d", "c": "2e7d2c03a9507ae265ecf5b5356885a53393a2029d241394997265a1a25aefc6", "d": "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d": "62af5c3cb8da3e4f25061e829ebeea5c7513c54949115b1acc225930a90154da", "2e7d2c03a9507ae265ecf5b5356885a53393a2029d241394997265a1a25aefc618ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4": "d3a0f1c792ccf7f1708d5422696263e35755a86917ea76ef9242bd4a8cf4891a", "62af5c3cb8da3e4f25061e829ebeea5c7513c54949115b1acc225930a90154dad3a0f1c792ccf7f1708d5422696263e35755a86917ea76ef9242bd4a8cf4891a": "58c89d709329eb37285837b042ab6ff72c7c8f74de0446b091b6a0131c102cfd" }

verify tx by merkle tree:

tx 1: True
tx 2: False