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
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}")
核心步骤:
- 数据结构化:将备注信息、时间戳、地址打包成标准格式
- 哈希计算:使用SHA-256生成数据指纹
- 私钥签名:用以太坊账户对哈希进行ECDSA签名
- 链上提交:通过智能合约存储签名数据
关键点:
- 时间戳防重放
- JSON序列化保持一致性
- 签名验证确保数据完整性
一句话建议: 确保使用安全的私钥管理和合适的哈希算法。

