《区块链公链数据分析简易速速上手小册》第3章:区块链数据结构(2024 最新版)

在这里插入图片描述

文章目录

  • 3.1 区块和交易的结构
    • 3.1.1 基础知识
    • 3.1.2 重点案例:构建简单的区块链
    • 3.1.3 拓展案例 1:验证交易签名
        • 生成密钥对
        • 签名交易
        • 验证签名
        • 完整的交易签名与验证演示
    • 3.1.4 拓展案例 2:监听和解析区块链事件
        • 代币合约示例(Solidity)
        • Python 脚本监听和解析事件
        • 结论
  • 3.2 智能合约数据解析
    • 3.2.1 基础知识
    • 3.2.2 重点案例:读取以太坊智能合约状态
        • 步骤1:准备智能合约
        • 步骤2:安装Web3.py
        • 步骤3:编写Python脚本读取合约状态
        • 结论
    • 3.2.3 拓展案例 1:监听智能合约事件
        • 智能合约示例(Solidity)
        • 步骤1:安装 Web3.py
        • 步骤2:编写 Python 脚本以监听事件
        • 注意事项
    • 3.2.4 拓展案例 2:向智能合约发送交易
        • 智能合约示例(Solidity)
        • 步骤1:准备环境
        • 步骤2:编写Python脚本发送交易
        • 注意事项
  • 3.3 链上与链下数据
    • 3.3.1 基础知识
    • 3.3.2 重点案例:链上验证链下数据
        • 步骤1: 智能合约编写
        • 步骤2: 部署智能合约
        • 步骤3: 使用Python存储和验证数据哈希
        • 结论
    • 3.3.3 拓展案例 1:使用 IPFS 存储链下数据
        • 步骤1: 安装IPFS和Python客户端
        • 步骤2: 启动IPFS守护进程
        • 步骤3: 使用Python脚本存储数据到IPFS
        • 步骤4: 将IPFS哈希值存储到以太坊智能合约
        • 结论
    • 3.3.4 拓展案例 2:链下数据的链上验证
        • 步骤1: 智能合约编写
        • 步骤2: 部署智能合约
        • 步骤3: 使用Python存储和验证数据哈希
        • 结论

3.1 区块和交易的结构

3.1.1 基础知识

在区块链的世界里,一切都始于区块和交易。这两个概念是构成任何区块链网络基础的核心元素。

  • 区块:区块是区块链数据结构的主体,它包含了一系列的交易。每个区块都有一个唯一的区块头,其中包含了重要的元数据,如前一个区块的哈希值(确保区块之间的连接)、时间戳(记录区块创建的时间)、难度目标(用于工作量证明算法)和一个称为nonce的值(使区块的哈希值满足网络难度要求)。

  • 交易:交易是区块链网络中传输资产或数据的基本单位。每笔交易都包含了一系列的输入和输出,输入指的是资产的来源,输出指的是资产的去向。交易一旦被网络验证并加入到一个区块中,就会被永久记录在区块链上。

3.1.2 重点案例:构建简单的区块链

让我们使用Python来模拟构建一个包含基本区块和交易结构的简单区块链。这个示例将帮助我们理解区块链是如何一步步构建并将交易记录在区块中的。

import hashlib
import json
from time import timeclass Blockchain:def __init__(self):self.chain = []self.current_transactions = []self.new_block(previous_hash='1', proof=100)  # 创世区块def new_block(self, proof, previous_hash=None):block = {'index': len(self.chain) + 1,'timestamp': time(),'transactions': self.current_transactions,'proof': proof,'previous_hash': previous_hash or self.hash(self.chain[-1]),}self.current_transactions = []self.chain.append(block)return blockdef new_transaction(self, sender, recipient, amount):self.current_transactions.append({'sender': sender,'recipient': recipient,'amount': amount,})return self.last_block['index'] + 1@staticmethoddef hash(block):block_string = json.dumps(block, sort_keys=True).encode()return hashlib.sha256(block_string).hexdigest()@propertydef last_block(self):return self.chain[-1]# 实例化Blockchain
blockchain = Blockchain()# 创建一个新交易
blockchain.new_transaction(sender="Alice", recipient="Bob", amount=100)# 挖掘一个新区块
blockchain.new_block(proof=12345)print(blockchain.chain)

3.1.3 拓展案例 1:验证交易签名

在区块链系统中,交易签名是确保交易安全性和完整性的关键。签名机制允许网络验证交易是否真的由交易发起者发起,而没有被第三方篡改。在这个扩展案例中,我们将使用Python演示如何生成密钥对、签名交易以及验证交易签名。

首先,确保安装了必要的Python库:

pip install ecdsa
生成密钥对

我们将使用椭圆曲线数字签名算法(ECDSA),这是比特币和许多其他加密货币使用的签名算法。

from ecdsa import SigningKey, SECP256k1# 生成ECDSA密钥对
sk = SigningKey.generate(curve=SECP256k1)  # 私钥
vk = sk.verifying_key  # 公钥private_key = sk.to_string().hex()
public_key = vk.to_string().hex()print(f"Private Key: {private_key}")
print(f"Public Key: {public_key}")
签名交易

使用生成的私钥对一条交易信息进行签名。

message = "Alice pays Bob 1 BTC"
signature = sk.sign(message.encode()).hex()print(f"Message: {message}")
print(f"Signature: {signature}")
验证签名

最后,我们将展示如何使用公钥和签名来验证消息。

from ecdsa import VerifyingKey# 将公钥和签名转换回相应格式
vk = VerifyingKey.from_string(bytes.fromhex(public_key), curve=SECP256k1)
signature_bytes = bytes.fromhex(signature)# 验证签名
try:is_valid = vk.verify(signature_bytes, message.encode())print("Signature is valid." if is_valid else "Signature is invalid.")
except Exception as e:print(f"Signature verification failed: {str(e)}")
完整的交易签名与验证演示

将上述片段组合起来,我们就得到了一个完整的交易签名与验证的演示。这个过程从生成密钥对开始,接着用私钥签名一条简单的消息(模拟交易),最后使用公钥验证签名的有效性。

通过这个案例,我们可以深入理解数字签名在区块链交易安全中的关键作用。数字签名不仅确保了交易的非抵赖性,还验证了交易的完整性和发起人的身份,是区块链技术核心安全机制的重要组成部分。

3.1.4 拓展案例 2:监听和解析区块链事件

监听和解析区块链事件,尤其是在以太坊这样的支持智能合约的平台上,对于开发去中心化应用(DApps)非常关键。它允许应用实时响应合约中发生的特定活动,如代币转移、投票结果或其他自定义事件。以下案例将展示如何使用 Python 和 Web3.py 监听以太坊智能合约事件,并对事件数据进行解析。

首先,确保你已经安装了 Web3.py 库:

pip install web3

假设我们有一个简单的 ERC-20 代币合约,其中包含一个Transfer事件,每当代币被转移时都会触发该事件。

代币合约示例(Solidity)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;contract SimpleToken {event Transfer(address indexed from, address indexed to, uint256 value);// 假设的代币转移函数function transfer(address _to, uint256 _value) external {// ...执行转移逻辑emit Transfer(msg.sender, _to, _value);}
}
Python 脚本监听和解析事件

以下Python脚本示例展示了如何连接到以太坊网络,订阅Transfer事件,并打印事件详情。

from web3 import Web3# 使用Infura的WebSocket服务连接到以太坊主网络
w3 = Web3(Web3.WebsocketProvider('wss://mainnet.infura.io/ws/v3/YOUR_INFURA_PROJECT_ID'))# 假设合约地址和ABI
contract_address = '0xYourContractAddress'
contract_abi = json.loads('''[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]''')# 创建合约对象
contract = w3.eth.contract(address=contract_address, abi=contract_abi)# 创建事件过滤器
transfer_event_filter = contract.events.Transfer.createFilter(fromBlock='latest')print("Listening for Transfer events...")while True:# 检查新的事件for event in transfer_event_filter.get_new_entries():handle_event(event)time.sleep(10)def handle_event(event):print(f"New Transfer event:\n From: {event['args']['from']}\n To: {event['args']['to']}\n Value: {event['args']['value']} tokens")

在上述代码中,YOUR_INFURA_PROJECT_ID需要替换为你的Infura项目ID,0xYourContractAddress需要替换为你的代币合约地址。contract_abi是合约的ABI,其中应包含你想要监听的事件定义。

这个脚本使用了Web3.py的事件过滤器功能来监听特定的Transfer事件,并在新事件到达时通过handle_event函数进行处理。这个处理函数简单地打印了事件的详细信息,包括转账的发送方、接收方和转移的代币数量。

结论

通过这个案例,我们展示了如何在以太坊区块链上监听和解析智能合约事件。这种能力对于开发实时响应链上活动的DApps至关重要。无论是追踪代币交易,还是其他基于事件的合约逻辑,使用Web3.py监听事件提供了一个强大且灵活的方法来增强应用的功能和用户体验。

通过这些案例,我们探索了区块链的基础数据结构,从构建和记录交易到验证交易的完整性和监听链上事件。这些操作是构建任何区块链应用的基石,理解它们对于任何 aspiring 区块链开发者来说都是必不可少的。

3.2 智能合约数据解析

智能合约是区块链技术的一项革命性创新,它允许在没有中介的情况下自动执行合约条款。这一切都是通过在区块链上编写和部署代码实现的。了解如何解析智能合约数据对于开发去中心化应用(DApp)、执行自动化测试或进行区块链数据分析至关重要。

3.2.1 基础知识

  • 智能合约:是存储在区块链上的一段程序,它能够在满足预设条件时自动执行预定义的操作。
  • 事件(Events):智能合约可以定义和触发事件,这些事件会被记录在区块链上,应用程序可以监听和响应这些事件。
  • 函数调用:智能合约包含可被外部或合约内部调用的函数,这些函数可以读取或修改合约的状态。

3.2.2 重点案例:读取以太坊智能合约状态

假设我们有一个部署在以太坊上的智能合约,该合约包含一个可以公开访问的状态变量storedData,以及一个函数getStoredData用于返回这个变量的值。我们的目标是使用Python和Web3.py库来读取这个智能合约状态变量的当前值。

步骤1:准备智能合约

首先,假设智能合约代码如下(Solidity语言):

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;contract SimpleStorage {uint storedData;constructor(uint initialValue) {storedData = initialValue;}function setStoredData(uint x) public {storedData = x;}function getStoredData() public view returns (uint) {return storedData;}
}

智能合约部署在以太坊网络上后,我们可以通过它的ABI和地址与之交互。

步骤2:安装Web3.py

确保你已经安装了Web3.py库:

pip install web3
步骤3:编写Python脚本读取合约状态

以下是使用Web3.py读取智能合约状态的Python脚本示例。在这个示例中,我们将连接到以太坊网络(通过Infura),使用合约的ABI和地址来创建一个合约对象,然后调用getStoredData函数来获取storedData变量的值。

from web3 import Web3
import json# 连接到以太坊节点
infura_url = 'https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID'
w3 = Web3(Web3.HTTPProvider(infura_url))# 确认连接成功
if w3.isConnected():print("Connected to Ethereum network")# 智能合约ABI和地址
contract_abi = json.loads('[YOUR_CONTRACT_ABI_HERE]')
contract_address = 'YOUR_CONTRACT_ADDRESS_HERE'# 创建智能合约对象
contract = w3.eth.contract(address=contract_address, abi=contract_abi)# 调用合约的getStoredData函数
stored_data = contract.functions.getStoredData().call()
print(f"The stored data is: {stored_data}")

在上面的代码中,你需要替换YOUR_INFURA_PROJECT_IDYOUR_CONTRACT_ABI_HEREYOUR_CONTRACT_ADDRESS_HERE为你自己的Infura项目ID、智能合约的ABI和合约地址。

结论

通过这个案例,我们演示了如何使用Python和Web3.py库来读取以太坊智能合约中的状态变量。这种方法可以用来访问智能合约的任何公开状态或执行其任何公开函数,为开发去中心化应用(DApps)提供了强大的基础。了解如何与智能合约交互并解析其数据对于构建复杂的区块链应用至关重要。

3.2.3 拓展案例 1:监听智能合约事件

在许多去中心化应用(DApps)中,实时监听智能合约事件并对其做出响应是一个常见且关键的需求。这可以用于追踪代币转移、用户投票、状态更新等重要活动。以下案例演示了如何使用Python和Web3.py监听以太坊智能合约的事件。

假设我们有一个智能合约,它定义了一个ValueChanged事件,每当合约中的某个值被更新时就会触发这个事件。

智能合约示例(Solidity)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;contract SimpleStorage {uint public storedData;event ValueChanged(uint oldValue, uint newValue);function set(uint x) public {emit ValueChanged(storedData, x);storedData = x;}
}
步骤1:安装 Web3.py

确保你的环境中已安装Web3.py:

pip install web3
步骤2:编写 Python 脚本以监听事件

接下来,我们将编写一个Python脚本,该脚本通过Infura连接到以太坊网络,并监听ValueChanged事件。

from web3 import Web3# 使用Infura的WebSocket服务连接到以太坊网络
w3 = Web3(Web3.WebsocketProvider('wss://mainnet.infura.io/ws/v3/YOUR_INFURA_PROJECT_ID'))# 智能合约地址和ABI
contract_address = '0xYourContractAddress'
contract_abi = json.loads('[YOUR_CONTRACT_ABI]')contract = w3.eth.contract(address=contract_address, abi=contract_abi)# 创建事件过滤器
value_changed_filter = contract.events.ValueChanged.createFilter(fromBlock='latest')print("Listening for ValueChanged events...")# 轮询以检查新事件
while True:for event in value_changed_filter.get_new_entries():print(f"Old Value: {event['args']['oldValue']}, New Value: {event['args']['newValue']}")time.sleep(10)

在这段代码中,将YOUR_INFURA_PROJECT_ID替换为你的Infura项目ID,0xYourContractAddress替换为智能合约的地址,[YOUR_CONTRACT_ABI]替换为合约的ABI。这段脚本首先创建了一个事件过滤器,然后进入一个循环,不断检查并打印新的ValueChanged事件。

注意事项
  • 使用WebSocket提供者(WebsocketProvider)对于监听事件是必需的,因为它支持订阅和实时更新,而HTTP提供者不支持这些功能。
  • 在生产环境中,你可能需要考虑错误处理和重新连接逻辑,以确保应用能够持续稳定地监听事件。

通过这个案例,我们展示了如何监听并处理以太坊智能合约中的事件,这对于构建响应式和交互式的DApps至关重要。监听智能合约事件是区块链开发中的一个强大工具,它可以帮助开发者实时捕捉到链上发生的关键活动,并据此执行相应的逻辑。

3.2.4 拓展案例 2:向智能合约发送交易

在以太坊上,向智能合约发送交易是一种常见的操作,用于执行合约的函数。这种操作可以改变合约的状态或触发链上的某些活动。以下案例演示了如何使用Python和Web3.py向以太坊智能合约发送交易。

假设我们有一个简单的智能合约,它允许存储和更新一个数值。

智能合约示例(Solidity)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;contract SimpleStorage {uint public storedData;function set(uint x) public {storedData = x;}
}

此合约包含一个名为set的函数,允许更新storedData变量的值。

步骤1:准备环境

确保你已安装Web3.py库:

pip install web3
步骤2:编写Python脚本发送交易

接下来,我们将编写一个Python脚本,通过Infura连接到以太坊网络,并发送一个交易来调用set函数。

from web3 import Web3
from web3.middleware import geth_poa_middleware# 使用Infura的HTTP服务连接到以太坊网络
w3 = Web3(Web3.HTTPProvider('https://rinkeby.infura.io/v3/YOUR_INFURA_PROJECT_ID'))
w3.middleware_onion.inject(geth_poa_middleware, layer=0)# 智能合约地址和ABI
contract_address = '0xYourContractAddress'
contract_abi = json.loads('[YOUR_CONTRACT_ABI]')contract = w3.eth.contract(address=contract_address, abi=contract_abi)# 发送交易需要的账户和私钥
account = '0xYourAccountAddress'
private_key = 'YourPrivateKey'# 构建交易
nonce = w3.eth.getTransactionCount(account)
tx = contract.functions.set(123).buildTransaction({'chainId': 4,  # Rinkeby测试网络的chain ID'gas': 2000000,'gasPrice': w3.toWei('50', 'gwei'),'nonce': nonce,
})# 签名交易
signed_tx = w3.eth.account.sign_transaction(tx, private_key)# 发送交易
tx_hash = w3.eth.sendRawTransaction(signed_tx.rawTransaction)# 获取交易哈希值
print(f"Transaction hash: {tx_hash.hex()}")

在这个脚本中,替换YOUR_INFURA_PROJECT_ID0xYourContractAddress[YOUR_CONTRACT_ABI]0xYourAccountAddressYourPrivateKey为你自己的值。

注意事项
  • 安全性:处理私钥时要非常小心,确保不要在公共代码库或不安全的地方暴露私钥。
  • Gas费用:发送交易需要支付Gas费用,因此确保你的账户有足够的以太币来支付。
  • 测试网络:在实际将交易发送到主网之前,强烈推荐在测试网络(如Rinkeby)上进行测试。

通过这个案例,我们演示了如何向以太坊智能合约发送交易以执行其函数,这是开发去中心化应用(DApps)的一个重要环节。理解如何与智能合约交互、发送交易和管理Gas费用对于区块链开发者来说是基本技能。

通过这些案例,我们展示了如何与以太坊智能合约进行交互,包括读取合约状态、监听事件以及发送交易以调用合约函数。这些技能是开发去中心化应用和进行区块链数据分析的基础,为开发者提供了强大的工具来构建复杂和高效的区块链应用。

3.3 链上与链下数据

在区块链应用开发中,理解链上和链下数据的区别及其应用是至关重要的。这不仅关乎数据的存储和处理方式,也影响到应用的设计和性能。

3.3.1 基础知识

  • 链上数据:直接存储在区块链上的数据。它的特点是不可篡改、透明且永久保存,适合存储交易记录、智能合约状态等关键信息。但由于存储成本较高,通常不适合存储大量数据。
  • 链下数据:存储在区块链外部的数据。链下数据可以存储在传统数据库、文件系统或任何其他形式的数据存储系统中。它适合存储大量数据,如应用日志、复杂的文档等,但不享有区块链数据的安全性和不可篡改性。

3.3.2 重点案例:链上验证链下数据

在区块链应用开发中,经常面临一个问题:如何有效地存储和验证大量数据。由于直接在链上存储数据成本较高,一种常见的解决方案是将数据存储在链下(如在服务器或分布式文件系统中),同时在链上存储数据的指纹(通常是数据的哈希值)以保证数据的不可篡改性和可验证性。

以下案例演示了如何使用Python和Web3.py以及以太坊智能合约来实现链上验证链下数据的完整性。

步骤1: 智能合约编写

首先,编写一个简单的智能合约,该合约允许用户存储和检索数据哈希值。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;contract DataHashStorage {mapping(bytes32 => bool) public hashExists;event HashStored(bytes32 dataHash);function storeDataHash(bytes32 dataHash) public {require(!hashExists[dataHash], "Data hash already stored.");hashExists[dataHash] = true;emit HashStored(dataHash);}function verifyDataHash(bytes32 dataHash) public view returns (bool) {return hashExists[dataHash];}
}

该合约包含一个storeDataHash函数用于存储数据哈希值,和一个verifyDataHash函数用于验证给定的哈希值是否已经被存储。

步骤2: 部署智能合约

使用Remix或Truffle等工具部署智能合约到以太坊网络,并记录合约地址。

步骤3: 使用Python存储和验证数据哈希

首先,安装Web3.py库。

pip install web3

接下来,编写Python脚本来计算链下数据的哈希值,存储这个哈希值到智能合约,并验证它。

from web3 import Web3
import hashlib# 连接到以太坊节点
w3 = Web3(Web3.HTTPProvider('https://rinkeby.infura.io/v3/YOUR_INFURA_PROJECT_ID'))# 智能合约地址和ABI
contract_address = '0xYourContractAddress'
contract_abi = json.loads('[YOUR_CONTRACT_ABI]')contract = w3.eth.contract(address=contract_address, abi=contract_abi)# 链下数据
data = "This is an example of off-chain data."
data_hash = hashlib.sha256(data.encode()).hexdigest()# 发送交易存储数据哈希到智能合约
# 注意: 这里需要账户和私钥进行交易签名
account = w3.eth.account.privateKeyToAccount('YourPrivateKey')
nonce = w3.eth.getTransactionCount(account.address)
tx = contract.functions.storeDataHash(data_hash).buildTransaction({'chainId': 4,  # Rinkeby测试网络的chain ID'gas': 200000,'gasPrice': w3.toWei('50', 'gwei'),'nonce': nonce,
})
signed_tx = w3.eth.account.sign_transaction(tx, 'YourPrivateKey')
tx_hash = w3.eth.sendRawTransaction(signed_tx.rawTransaction)# 等待交易被挖矿
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)# 验证数据哈希
verified = contract.functions.verifyDataHash(data_hash).call()
print(f"Data hash verified: {verified}")

在这个脚本中,替换YOUR_INFURA_PROJECT_ID0xYourContractAddress[YOUR_CONTRACT_ABI]YourPrivateKey为你自己的值。

结论

通过这个案例,我们展示了如何将链下数据的哈希值存储到以太坊智能合约中,并实现了一个机制来验证链下数据的完整性和真实性。这种方法结合了区块链的不可篡改性和链下数据存储的灵活性与成本效益,为开发复杂的区块链应用提供了一种有效的数据管理策略。

3.3.3 拓展案例 1:使用 IPFS 存储链下数据

IPFS(InterPlanetary File System)是一个分布式文件系统,它允许存储和访问大量的数据,同时提供了一个唯一的哈希值用于数据的访问和验证。IPFS是链下数据存储的理想选择,因为它提供了去中心化和持久性,同时能够通过链上存储的哈希值来验证数据的完整性。以下案例演示了如何使用Python将数据存储到IPFS,并将对应的哈希值记录在以太坊智能合约中。

步骤1: 安装IPFS和Python客户端

首先,确保你的系统中安装了IPFS。你可以从IPFS官网下载并安装IPFS。

然后,安装Python的IPFS客户端库:

pip install ipfshttpclient
步骤2: 启动IPFS守护进程

在终端运行以下命令来启动IPFS守护进程:

ipfs daemon
步骤3: 使用Python脚本存储数据到IPFS

接下来,我们将使用Python脚本来存储数据到IPFS,并获取数据的唯一哈希值。

import ipfshttpclient# 连接到本地IPFS节点
client = ipfshttpclient.connect('/ip4/127.0.0.1/tcp/5001/http')# 要存储到IPFS的数据
data = "Hello, IPFS and Ethereum!"# 添加数据到IPFS
res = client.add_str(data)
ipfs_hash = resprint(f"Data stored on IPFS with hash: {ipfs_hash}")
步骤4: 将IPFS哈希值存储到以太坊智能合约

现在,我们有了存储在IPFS上的数据哈希值,下一步是将这个哈希值存储到以太坊智能合约中,以便链上验证。

假设我们已经有一个智能合约,它有一个函数可以存储和验证IPFS哈希值。我们将使用Web3.py来与以太坊交互。

from web3 import Web3# 连接到以太坊
w3 = Web3(Web3.HTTPProvider('https://rinkeby.infura.io/v3/YOUR_INFURA_PROJECT_ID'))# 智能合约地址和ABI
contract_address = '0xYourContractAddress'
contract_abi = '[YOUR_CONTRACT_ABI]'contract = w3.eth.contract(address=contract_address, abi=contract_abi)# 账户和私钥
account = '0xYourAccountAddress'
private_key = 'YourPrivateKey'# 构建交易
nonce = w3.eth.getTransactionCount(account)
tx = contract.functions.storeIPFSHash(ipfs_hash).buildTransaction({'chainId': 4,  # Rinkeby测试网络的chain ID'gas': 200000,'gasPrice': w3.toWei('50', 'gwei'),'nonce': nonce,
})# 签名交易
signed_tx = w3.eth.account.sign_transaction(tx, private_key)# 发送交易
tx_hash = w3.eth.sendRawTransaction(signed_tx.rawTransaction)# 获取交易哈希值
print(f"Transaction hash: {tx_hash.hex()}")

在这个脚本中,替换YOUR_INFURA_PROJECT_ID0xYourContractAddress[YOUR_CONTRACT_ABI]0xYourAccountAddressYourPrivateKey为你自己的值。

结论

通过这个案例,我们演示了如何结合使用IPFS和以太坊来存储和验证大量的链下数据。这种方法利用了IPFS的分布式存储能力和以太坊智能合约的不可篡改性,为构建去中心化应用提供了一个高效、安全的数据存储和验证解决方案。

3.3.4 拓展案例 2:链下数据的链上验证

链下数据的链上验证是确保数据完整性和真实性的关键机制,特别是在去中心化应用(DApp)中处理大量数据时。这个过程通常涉及两个步骤:首先将数据存储在链下,然后将数据的哈希值或数字指纹存储在链上。当需要验证数据时,可以重新计算其哈希值并与链上存储的哈希值进行比对。

在本案例中,我们将使用Python演示如何实现链下数据的链上验证,包括如何通过智能合约存储和验证数据哈希。

步骤1: 智能合约编写

假设我们有一个简单的智能合约,用于存储和验证数据哈希:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;contract DataVerifier {mapping(bytes32 => bool) private hashes;// 事件,用于记录数据哈希已存储event HashStored(bytes32 dataHash);// 存储数据哈希function storeHash(bytes32 dataHash) public {require(!hashes[dataHash], "Hash already stored.");hashes[dataHash] = true;emit HashStored(dataHash);}// 验证数据哈希function verifyHash(bytes32 dataHash) public view returns (bool) {return hashes[dataHash];}
}
步骤2: 部署智能合约

使用你偏好的工具(如Truffle、Hardhat或Remix)将智能合约部署到以太坊网络(主网或测试网)。

步骤3: 使用Python存储和验证数据哈希

首先,确保安装了Web3.py库:

pip install web3

接下来,我们将计算链下数据的哈希值,通过智能合约存储这个哈希值,然后验证它。

from web3 import Web3
import hashlib# 连接到以太坊
w3 = Web3(Web3.HTTPProvider('https://rinkeby.infura.io/v3/YOUR_INFURA_PROJECT_ID'))# 智能合约地址和ABI
contract_address = '0xYourContractAddress'
contract_abi = '[YOUR_CONTRACT_ABI]'contract = w3.eth.contract(address=contract_address, abi=contract_abi)# 链下数据
data = "This is an example of off-chain data."
data_hash = hashlib.sha256(data.encode()).hexdigest()# 转换哈希值为bytes32
data_hash_bytes32 = w3.toBytes(hexstr=data_hash)# 发送交易存储数据哈希到智能合约
account = '0xYourAccountAddress'
private_key = 'YourPrivateKey'
nonce = w3.eth.getTransactionCount(account)
tx = contract.functions.storeHash(data_hash_bytes32).buildTransaction({'chainId': 4,  # Rinkeby测试网络的chain ID'gas': 2000000,'gasPrice': w3.toWei('50', 'gwei'),'nonce': nonce,
})signed_tx = w3.eth.account.sign_transaction(tx, private_key)
tx_hash = w3.eth.sendRawTransaction(signed_tx.rawTransaction)
print(f"Transaction hash: {tx_hash.hex()}")# 等待交易被挖掘
tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)# 验证数据哈希
verified = contract.functions.verifyHash(data_hash_bytes32).call()
print(f"Data hash verified: {verified}")

在这个脚本中,替换YOUR_INFURA_PROJECT_ID0xYourContractAddress[YOUR_CONTRACT_ABI]0xYourAccountAddressYourPrivateKey为你自己的值。

结论

这个案例展示了如何利用智能合约在链上存储和验证链下数据的哈希值。这种机制增加了数据处理的透明度和安全性,同时依然能够利用链下存储的高效性和低成本。这对于那些需要处理大量数据的去中心化应用尤其有用,例如在供应链管理、版权认证和数据市场等领域。

通过这些案例,我们探讨了链上与链下数据的不同用途和如何将它们结合使用。存储关键验证信息到链上,同时将大量数据存储到链下,是一种既能利用区块链技术的安全性和透明度,又能有效管理成本和性能的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/468624.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电路设计(18)——9路抢答器的设计与制作

1.设计要求 设计、制作一台9路抢答器,抢答器应符合如下工作过程: 每次抢答前,主持人首先按下复位键,将抢答器上“抢答号”数显复位,显示为“0”。接着,主持人念答题内容,念毕即叫“抢答…

详解Vue文件结构+实现一个简单案例

💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢…

【STL】string的模拟实现

string类的模拟实现 一、接口函数总览二、默认成员函数1、构造函数2、拷贝构造函数(1)写法一:传统写法(2)写法二:现代写法 3、赋值运算符重载函数(1)写法一:传统写法&…

【数据结构】链表OJ面试题5《链表的深度拷贝》(题库+解析)

1.前言 前五题在这http://t.csdnimg.cn/UeggB 后三题在这http://t.csdnimg.cn/gbohQ 给定一个链表,判断链表中是否有环。http://t.csdnimg.cn/Rcdyc 给定一个链表,返回链表开始入环的第一个结点。 如果链表无环,则返回 NULLhttp://t.cs…

面向对象2:继承

目录 2.1继承 2.2 继承的好处 2.3 权限修饰符 2.4 单继承、Object 2.5 方法重写 2.6 子类中访问成员的特点 2.7 子类中访问构造器的特点 面向对象1:静态 2.1继承 向对象编程之所以能够能够被广大开发者认可,有一个非常重要的原因,是…

Qt 软件封装与打包

1. Qt 软件封装 1、首先以 release 方式进行编译,将生成的 CloudOne.exe 文件复制到 D:\CloudApp 文件夹(自行创建) 2、打开 Qt 命令行工具(如下图所示),并按顺序输入如下指令 cd D:\CloudApp windeployq…

linux应用 进程间通信之共享内存(POSIX)

1、前言 1.1 定义 POSIX共享内存是一种在UNIX和类UNIX系统上可用的进程间通信机制。它允许多个进程共享同一块内存区域,从而可以在这块共享内存上进行读写操作。 1.2 应用场景 POSIX共享内存适用于需要高效地进行大量数据交换的场景,比如多个进程需要…

【JavaEE】----SpringBoot的创建和使用

目录 1.Spring与SpringBoot的区别(面试) 2. SpringBoot的创建 3.SpringBoot创建时的问题及解决 4.SpringBoot的目录学习 5.创建一个SpringBoot 项目并且启动 1.Spring与SpringBoot的区别(面试) Spring 的诞⽣是为了简化 Java 程…

2023年全国职业院校技能大赛软件测试赛题第5套

2023年全国职业院校技能大赛 软件测试赛题第5套 赛项名称: 软件测试 英文名称: Software Testing 赛项编号: GZ034 归属产业: 电子与信息大类 …

如何生成狗血短剧

如何生成狗血短剧 狗血短剧剧本将上述剧本转成对话 狗血短剧剧本 标题:《爱的轮回》 类型:现代都市爱情短剧 角色: 1. 林晓雪 - 女,25岁,职场小白,善良单纯 2. 陆子轩 - 男,28岁,公…

内网穿透 | 推荐两个免费的内网穿透工具

目录 1、简介 2、Ngrok 2.1、下载安装 2.2、运行 2.3、固定域名 2.4、配置多服务 3、cpolar 3.1、下载安装 3.2、运行 🍃作者介绍:双非本科大三网络工程专业在读,阿里云专家博主,专注于Java领域学习,擅长web应…

【每日一题】尾随零

尾随零 目录 思路:代码实现: 思路: 最开始看到这题就只想到规规矩矩的做题,先算阶乘在算0,后来提交时总是提示溢出,不死心,改来改去最后没招了。 后来看题解才知道要看5的个数! …