python-3.x - Hyperledger Sawtooth 供应链发送交易
问题描述
我正在尝试将第一个区块添加到供应链中,因为验证器不接受该批次。
[2019-11-05 17:40:31.594 DEBUG publisher] Batch c14df4b31bd7d52cf033a0eb1436b98be3d9ff6b06affbd73ae55f11a7cc0cc33aa6f160f7712d628e2ac644b4b1804e3156bc8190694cb9c468f4ec70b9eb05 invalid, not added to block.
[2019-11-05 17:40:31.595 DEBUG publisher] Abandoning block (1, S:, P:eb6af88e): no batches added
我在 Ubuntu 16.04 上安装了 Sawtooth 和供应链。我正在使用以下 Python 代码发送交易。我不确定有效载荷。我从 fish 客户端示例的示例数据中得到了这个。是否有必要更改密钥?
#Creating a Private Key and Signer
from sawtooth_signing import create_context
from sawtooth_signing import CryptoFactory
from hashlib import sha512
context = create_context('secp256k1')
private_key = context.new_random_private_key()
signer = CryptoFactory(context).new_signer(private_key)
public_key = signer.get_public_key()
#Encoding Your Payload
import cbor
payload = {
"username": "ahab",
"password": "ahab",
"publicKey": public_key.as_hex(),
"name": "Ahab",
"email": "ahab@pequod.net",
"privateKey": "063f9ca21d4ef4955f3e120374f7c22272f42106c466a91d01779efba22c2cb6",
"encryptedKey": "{\"iv\":\"sKGty1gSvZGmCwzkGy0vvg==\",\"v\":1,\"iter\":10000,\"ks\":128,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"lYT7rTJpTV0=\",\"ct\":\"taU8UNB5oJrquzEiXBV+rTTnEq9XmaO9BKeLQQWWuyXJdZ6wR9G+FYrKPkYnXc30iS/9amSG272C8qqnPdM4OE0dvjIdWgSd\"}",
"hashedPassword": "KNYr+guWkg77DbaWofgK72LrNdaQzzJGIkk2rEHqP9Y="
}
payload_bytes = cbor.dumps(payload)
#Create the Transaction Header
from hashlib import sha512
from sawtooth_sdk.protobuf.transaction_pb2 import TransactionHeader
txn_header_bytes = TransactionHeader(
family_name='supply_chain',
family_version='1.1',
#inputs=[],
#outputs=[],
signer_public_key=signer.get_public_key().as_hex(),
# In this example, we're signing the batch with the same private key,
# but the batch can be signed by another party, in which case, the
# public key will need to be associated with that key.
batcher_public_key=signer.get_public_key().as_hex(),
# In this example, there are no dependencies. This list should include
# an previous transaction header signatures that must be applied for
# this transaction to successfully commit.
# For example,
# dependencies=['540a6803971d1880ec73a96cb97815a95d374cbad5d865925e5aa0432fcf1931539afe10310c122c5eaae15df61236079abbf4f258889359c4d175516934484a'],
dependencies=[],
payload_sha512=sha512(payload_bytes).hexdigest()
).SerializeToString()
#Create the Transaction
from sawtooth_sdk.protobuf.transaction_pb2 import Transaction
signature = signer.sign(txn_header_bytes)
txn = Transaction(
header=txn_header_bytes,
header_signature=signature,
payload= payload_bytes
)
#Create the BatchHeader
from sawtooth_sdk.protobuf.batch_pb2 import BatchHeader
txns = [txn]
batch_header_bytes = BatchHeader(
signer_public_key=signer.get_public_key().as_hex(),
transaction_ids=[txn.header_signature for txn in txns],
).SerializeToString()
#Create the Batch
from sawtooth_sdk.protobuf.batch_pb2 import Batch
signature = signer.sign(batch_header_bytes)
batch = Batch(
header=batch_header_bytes,
header_signature=signature,
transactions=txns
)
#Encode the Batch(es) in a BatchList
from sawtooth_sdk.protobuf.batch_pb2 import BatchList
batch_list_bytes = BatchList(batches=[batch]).SerializeToString()
#Submitting Batches to the Validator
import urllib.request
from urllib.error import HTTPError
try:
request = urllib.request.Request(
'http://localhost:8008/batches',
batch_list_bytes,
method='POST',
headers={'Content-Type': 'application/octet-stream'})
response = urllib.request.urlopen(request)
except HTTPError as e:
response = e.file
解决方案
我为我的情况找到了解决方案。我使用了 Supply Chain Repo 的 .proto 文件,并将这些文件编译为 Python 文件。然后我拿了供应链回购的addressing.py和supply_chain_message_factory.py。我更改了 supply_chain_message_factory.py 中的导入,现在我可以使用 main.py 创建代理。
from sc_message_factory import SupplyChainMessageFactory
import urllib.request
from urllib.error import HTTPError
#Create new agent
new_message = SupplyChainMessageFactory()
transaction = new_message.create_agent('test')
batch = new_message.create_batch(transaction)
try:
request = urllib.request.Request(
'http://localhost:8008/batches',
batch,
method='POST',
headers={'Content-Type': 'application/octet-stream'})
response = urllib.request.urlopen(request)
except HTTPError as e:
response = e.file
推荐阅读
- apache - ProxyPass 的 Apache 拆分通配符子域
- django - Django get() 缺少 1 个必需的位置参数:'header'
- python - PDF - 将单个单词拆分为单独的行 - Python 3
- ansible - 我应该在每个需要 root 权限的任务上使用 become: true
- c++ - websocket计时器滴答后提升asio短读错误
- javascript - 如何将对象的键值对插入数组?
- python - 如何检查列表参数是否为无
- c# - 是否有本地方式或通过 VS Extension for VS 2017/2019 从 C# POCO 自动生成 typescript .d 文件
- java - 使用 SpringBoot 向现有 mongodb 文档添加数据
- bash - 如果转换结果为单个十六进制字母 (Bash),则将十进制转换为十六进制并放置一个起始零