Skip to content

Instantly share code, notes, and snippets.

@vrde
Last active July 23, 2018 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vrde/314d20638fc2f3a105c2393837013031 to your computer and use it in GitHub Desktop.
Save vrde/314d20638fc2f3a105c2393837013031 to your computer and use it in GitHub Desktop.
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