Last active
July 23, 2018 18:32
-
-
Save vrde/314d20638fc2f3a105c2393837013031 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
from pprint import pprint | |
import base58 | |
import sha3 | |
from cryptoconditions import Ed25519Sha256 | |
from bigchaindb_driver.crypto import generate_keypair | |
remote = generate_keypair() | |
# The public key is known by the client | |
public_key = remote.public_key | |
# While the private key is securely stored in the server | |
private_key = remote.private_key | |
# The client prepares the transaction | |
operation = 'CREATE' | |
version = '2.0' | |
asset = { | |
'data': { | |
'bicycle': { | |
'manufacturer': 'bkfab', | |
'serial_number': 'abcd1234', | |
}, | |
}, | |
} | |
metadata = {'planet': 'earth'} | |
ed25519 = Ed25519Sha256(public_key=base58.b58decode(public_key)) | |
output = { | |
'amount': '1', | |
'condition': { | |
'details': { | |
'type': ed25519.TYPE_NAME, | |
'public_key': base58.b58encode(ed25519.public_key), | |
}, | |
'uri': ed25519.condition_uri, | |
}, | |
'public_keys': [public_key,], | |
} | |
outputs = [output,] | |
input_ = { | |
'fulfillment': None, | |
'fulfills': None, | |
'owners_before': [public_key,] | |
} | |
inputs = (input_,) | |
handcrafted_creation_tx = { | |
'asset': asset, | |
'metadata': metadata, | |
'operation': operation, | |
'outputs': outputs, | |
'inputs': inputs, | |
'version': version, | |
'id': None, | |
} | |
message = json.dumps( | |
handcrafted_creation_tx, | |
sort_keys=True, | |
separators=(',', ':'), | |
ensure_ascii=False, | |
) | |
message = sha3.sha3_256(message.encode()).digest() | |
# At this point, the client makes an HTTP request to sign the message. | |
# The server implements the following code, and returns the signature. | |
from nacl.signing import VerifyKey, SigningKey | |
sk = SigningKey(base58.b58decode(private_key)) | |
signature = sk.sign(message).signature | |
# After getting the signature, the client can fulfill the transaction. | |
ed25519.signature = signature | |
fulfillment_uri = ed25519.serialize_uri() | |
handcrafted_creation_tx['inputs'][0]['fulfillment'] = fulfillment_uri | |
json_str_tx = json.dumps( | |
handcrafted_creation_tx, | |
sort_keys=True, | |
separators=(',', ':'), | |
ensure_ascii=False, | |
) | |
creation_txid = sha3.sha3_256(json_str_tx.encode()).hexdigest() | |
handcrafted_creation_tx['id'] = creation_txid | |
# Extra: validate the signature in the transaction. | |
# | |
# Transaction validation is a three step process: | |
# 1. schema validation checks the structure of the transaction | |
# 2. signature validation checks the signature | |
# 3. spends validation checks if the inputs of the transaction are valid and | |
# can be spent. | |
# Note: in this snippet we skip step 3 | |
from bigchaindb.models import Transaction | |
# Step 1: check the transaction schema | |
transaction = Transaction.from_dict(handcrafted_creation_tx) | |
# Step 2: check the signature | |
# `inputs_valid` checks *only* the signature: | |
# enabling full validation would require to query the database as well, | |
# but for this use case we can skip it. | |
if transaction.inputs_valid(): | |
print('The transaction is VALID') | |
print() | |
else: | |
print('ERROR: Transaction is INVALID') | |
print() | |
pprint(handcrafted_creation_tx) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment