Python中如何实现用签名提交备注信息上链

用法:

先下载整个项目,解压缩后安装必要的 pip 库

git clone https://github.com/OpensourceBooks/blockchain

cd blockchain

pip3 install -r requirements.txt

演示

cd 7

python3 blockchain.py

创建一个发消息的地址和私钥:

python3 client.py -a n

返回类似如下信息:

address:Z/qsNWOAAWULpqvtM/OMHmJE+6PG0oPUsOMGk2ySYgrUB5noaZsD6b0NbbPgslr1cdninkqYKcJ+sx74/Mhn2A==

private_key:196f72bf05e307458a0691ca73a2981d859e499ef9fc264183feddde5bd47217

使用签名发消息上链

python3 client.py -a s -f Z/qsNWOAAWULpqvtM/OMHmJE+6PG0oPUsOMGk2ySYgrUB5noaZsD6b0NbbPgslr1cdninkqYKcJ+sx74/Mhn2A== -t Z/qsNWOAAWULpqvtM/OMHmJE+6PG0oPUsOMGk2ySYgrUB5noaZsD6b0NbbPgslr1cdninkqYKcJ+sx74/Mhn2A== -m hello -p 196f72bf05e307458a0691ca73a2981d859e499ef9fc264183feddde5bd47217

返回的信息类似如下:

[
  {
    "data": "Genesis Block",
    "hash": "65661446c4106d81e864fe4dca5fea70364023f881330017489207652d53e3fc",
    "index": 0,
    "previous_hash": 0,
    "timestamp": 1534499678402
  },
  {
    "data": {
      "from": "gwCSgiOvn0ndfftgsOIYNjPjEcT24BrMEWH7lZ5qCmFlyaUnR/frznDDFdfNSWJLGta14c+0gDUc7RS4kkf1aQ==",
      "memo": "hello",
      "to": "gwCSgiOvn0ndfftgsOIYNjPjEcT24BrMEWH7lZ5qCmFlyaUnR/frznDDFdfNSWJLGta14c+0gDUc7RS4kkf1aQ=="
    },
    "hash": "89f9e9c445690624dceca3ef8f3f43b65f6a6558ffd25c13bc952e9d7624838a",
    "index": 1,
    "previous_hash": "65661446c4106d81e864fe4dca5fea70364023f881330017489207652d53e3fc",
    "timestamp": 1534499684262
  },
  {
    "data": {
      "from": "Z/qsNWOAAWULpqvtM/OMHmJE+6PG0oPUsOMGk2ySYgrUB5noaZsD6b0NbbPgslr1cdninkqYKcJ+sx74/Mhn2A==",
      "memo": "hello",
      "to": "Z/qsNWOAAWULpqvtM/OMHmJE+6PG0oPUsOMGk2ySYgrUB5noaZsD6b0NbbPgslr1cdninkqYKcJ+sx74/Mhn2A=="
    },
    "hash": "144d2a6f6724b78f5ccd1c81e01fae8c6a7b9ec474a3131f94331203e9daa9a7",
    "index": 2,
    "previous_hash": "89f9e9c445690624dceca3ef8f3f43b65f6a6558ffd25c13bc952e9d7624838a",
    "timestamp": 1534501157600
  }
]

详情: https://github.com/OpensourceBooks/blockchain/blob/master/7/readme.md

项目地址: https://github.com/OpensourceBooks/blockchain


Python中如何实现用签名提交备注信息上链

1 回复

import hashlib
import json
from eth_account import Account
from web3 import Web3

class BlockchainCommit:
    def __init__(self, rpc_url, private_key):
        self.w3 = Web3(Web3.HTTPProvider(rpc_url))
        self.account = Account.from_key(private_key)
        
    def create_commitment(self, remark, timestamp=None):
        """创建带时间戳的备注数据结构"""
        if timestamp is None:
            timestamp = int(self.w3.eth.get_block('latest')['timestamp'])
            
        commitment = {
            'remark': remark,
            'timestamp': timestamp,
            'address': self.account.address
        }
        return commitment
    
    def hash_commitment(self, commitment):
        """计算备注数据的哈希值"""
        # 将字典转换为排序后的JSON字符串确保一致性
        commitment_str = json.dumps(commitment, sort_keys=True, separators=(',', ':'))
        return hashlib.sha256(commitment_str.encode()).hexdigest()
    
    def sign_commitment(self, commitment):
        """对备注数据进行签名"""
        # 先计算哈希
        commitment_hash = self.hash_commitment(commitment)
        
        # 使用以太坊账户签名
        signed_message = self.account.signHash(commitment_hash)
        
        return {
            'commitment': commitment,
            'signature': signed_message.signature.hex(),
            'hash': commitment_hash
        }
    
    def verify_signature(self, signed_data, signer_address=None):
        """验证签名"""
        if signer_address is None:
            signer_address = self.account.address
            
        # 重新计算哈希
        recalculated_hash = self.hash_commitment(signed_data['commitment'])
        
        # 恢复签名者地址
        recovered_address = Account.recoverHash(
            recalculated_hash,
            signature=signed_data['signature']
        )
        
        return recovered_address.lower() == signer_address.lower()
    
    def submit_to_contract(self, contract_address, abi, signed_data):
        """提交到智能合约(示例)"""
        contract = self.w3.eth.contract(address=contract_address, abi=abi)
        
        # 构建交易
        tx = contract.functions.commitRemark(
            signed_data['commitment']['remark'],
            signed_data['commitment']['timestamp'],
            signed_data['signature']
        ).build_transaction({
            'from': self.account.address,
            'nonce': self.w3.eth.get_transaction_count(self.account.address),
            'gas': 200000,
            'gasPrice': self.w3.eth.gas_price
        })
        
        # 签名并发送交易
        signed_tx = self.w3.eth.account.sign_transaction(tx, self.account.key)
        tx_hash = self.w3.eth.send_raw_transaction(signed_tx.rawTransaction)
        
        return tx_hash.hex()

# 使用示例
if __name__ == "__main__":
    # 配置(实际使用时替换为真实值)
    RPC_URL = "https://mainnet.infura.io/v3/YOUR_INFURA_KEY"
    PRIVATE_KEY = "0x你的私钥"
    CONTRACT_ADDRESS = "0x合约地址"
    
    # 初始化
    committer = BlockchainCommit(RPC_URL, PRIVATE_KEY)
    
    # 1. 创建备注
    remark = "项目里程碑完成 - 2024Q1"
    commitment = committer.create_commitment(remark)
    
    # 2. 签名
    signed_data = committer.sign_commitment(commitment)
    print(f"签名数据: {json.dumps(signed_data, indent=2)}")
    
    # 3. 验证签名
    is_valid = committer.verify_signature(signed_data)
    print(f"签名验证: {'通过' if is_valid else '失败'}")
    
    # 4. 提交到链上(需要合约支持)
    # tx_hash = committer.submit_to_contract(CONTRACT_ADDRESS, CONTRACT_ABI, signed_data)
    # print(f"交易哈希: {tx_hash}")

核心步骤:

  1. 数据结构化:将备注信息、时间戳、地址打包成标准格式
  2. 哈希计算:使用SHA-256生成数据指纹
  3. 私钥签名:用以太坊账户对哈希进行ECDSA签名
  4. 链上提交:通过智能合约存储签名数据

关键点:

  • 时间戳防重放
  • JSON序列化保持一致性
  • 签名验证确保数据完整性

一句话建议: 确保使用安全的私钥管理和合适的哈希算法。

回到顶部