Last active
September 4, 2019 09:34
-
-
Save jpopesculian/bcbe046cd77064085b5b27e2ddfc6a03 to your computer and use it in GitHub Desktop.
Zen Example
This file contains hidden or 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 hashlib | |
import base58 | |
import base64 | |
import json | |
from zenroom_minimal import Zenroom | |
from cryptoconditions import read_zencode | |
from cryptoconditions import ZenroomSha256 | |
from datetime import datetime | |
from bigchaindb_driver.crypto import generate_keypair | |
from bigchaindb_driver import BigchainDB | |
BDB_URL = 'http://localhost:9984/' | |
VERSION = '2.0' | |
def gen_keyring(): | |
zenroom = Zenroom(read_zencode) | |
zenroom.load(""" | |
Scenario 'signing': "Generate a new keyring" | |
Given a blank keyring | |
Then generate a new key pair | |
And serialize my keyring | |
And return 'serialized keyring' | |
""") | |
return json.loads(zenroom.eval())["serialized_keyring"] | |
def sign(message, keyring): | |
zenroom = Zenroom(read_zencode) | |
zenroom.load(""" | |
Scenario 'signing': "Sign a message" | |
Given that I am 'alice' | |
And a blank keyring | |
And the input 'message' | |
Then load my serialized private key | |
And decode base64 'message' | |
And sign 'message' | |
And encode base64 'signature' | |
And return 'signature' | |
""") | |
zenroom.load_data("{ message = '%s' }" % message) | |
zenroom.load_keys("{ alice = '%s' }" % json.dumps(keyring)) | |
return json.loads(zenroom.eval())["signature"] | |
def verify(message, signature, keyring): | |
zenroom = Zenroom(read_zencode) | |
zenroom.load(""" | |
Scenario 'signing': "Verify a message" | |
Given that I am 'alice' | |
And a blank keyring | |
And the input 'message' | |
And the input 'signature' | |
Then load my serialized public key | |
And decode base64 'message' | |
And decode base64 'signature' | |
And verify the signature for 'message' | |
And assert 'verified' | |
""") | |
zenroom.load_data("{ message = '%s', signature = '%s' }" %(message, signature)) | |
zenroom.load_keys("{ alice = '%s' }" % json.dumps(keyring)) | |
return json.loads(zenroom.eval()) | |
def build_tx(owner1, owner2, fulfillment): | |
tx_input = { | |
'fulfillment': None, | |
'fulfills': None, | |
'owners_before': (owner1.public_key,) | |
} | |
tx_output = { | |
'amount': '10', | |
'condition': { | |
'details': { | |
'type': fulfillment.TYPE_NAME, | |
'script': base58.b58encode(fulfillment.script).decode() | |
}, | |
'uri': fulfillment.condition.serialize_uri() | |
}, | |
'public_keys': (owner2.public_key,), | |
} | |
return { | |
'id': None, | |
'operation': 'CREATE', | |
'version': VERSION, | |
'asset': { 'data': { 'nonce': str(datetime.now()) } }, | |
'metadata': None, | |
'inputs': (tx_input,), | |
'outputs': (tx_output,) | |
} | |
def encode_tx(tx): | |
return json.dumps( | |
tx, | |
sort_keys=True, | |
separators=(',', ':'), | |
ensure_ascii=False | |
).encode() | |
def hash_tx(tx): | |
return hashlib.sha3_256(encode_tx(tx)).digest() | |
def create_id(tx): | |
return hashlib.sha3_256(encode_tx(tx)).hexdigest() | |
def sign_tx(tx, fulfillment, keyring): | |
message = base64.urlsafe_b64encode(hash_tx(tx))[0:-1].decode('utf-8') | |
signature = sign(message, keyring) | |
fulfillment.data = signature | |
tx['inputs'][0]['fulfillment'] = fulfillment.serialize_uri() | |
tx['id'] = create_id(tx) | |
return tx | |
owner1, owner2 = generate_keypair(), generate_keypair() | |
keyring = gen_keyring() | |
print("π Keys generated") | |
script = """ | |
Scenario 'signing': "Verify a message" | |
Given the constant 'public key' is '%s' | |
And a blank keyring | |
And the input 'message' | |
And the input 'signature' | |
Then load serialized public key from 'public key' | |
And decode base64 'message' | |
And decode base64 'signature' | |
And verify the signature for 'message' | |
And assert 'verified' | |
""" % keyring["public"] | |
fulfillment = ZenroomSha256(script=script) | |
tx = build_tx(owner1, owner2, fulfillment) | |
print("π¨ Transaction built") | |
tx = sign_tx(tx, fulfillment, keyring) | |
print("π Transaction signed") | |
returned_tx = BigchainDB(BDB_URL).transactions.send_async(tx) | |
print("π Transaction created") | |
print("") | |
print(returned_tx) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment