docs with code examples

This commit is contained in:
diminator 2016-04-12 13:20:34 +02:00
parent 5fa12c9744
commit 61c0da8212
No known key found for this signature in database
GPG Key ID: C3D8590E6D0D439A
3 changed files with 415 additions and 21 deletions

View File

@ -69,17 +69,52 @@ After a couple of seconds, we can check if the transactions was included in the
# retrieve a transaction from the bigchain
tx_retrieved = b.get_transaction(tx_signed['id'])
'id': '6539dded9479c47b3c83385ae569ecaa90bcf387240d1ee2ea3ae0f7986aeddd',
'transaction': { 'current_owner': 'pvGtcm5dvwWMzCqagki1N6CDKYs2J1cCwTNw8CqJic3Q',
'data': { 'hash': '872fa6e6f46246cd44afdb2ee9cfae0e72885fb0910e2bcf9a5a2a4eadb417b8',
'payload': {'msg': 'Hello BigchainDB!'}},
'input': None,
'new_owner': 'ssQnnjketNYmbU3hwgFMEQsc4JVYAmZyWHnHCtFS8aeA',
'operation': 'CREATE',
'timestamp': '1455108421.753908'}}
{
"id": "cdb6331f26ecec0ee7e67e4d5dcd63734e7f75bbd1ebe40699fc6d2960ae4cb2",
"transaction": {
"conditions": [
{
"cid": 0,
"condition": {
"details": {
"bitmask": 32,
"public_key": "DTJCqP3sNkZcpoSA8bCtGwZ4ASfRLsMFXZDCmMHzCoeJ",
"signature": null,
"type": "fulfillment",
"type_id": 4
},
"uri": "cc:1:20:uQjL_E_uT1yUsJpVi1X7x2G7B15urzIlKN5fUufehTM:98"
},
"new_owners": [
"DTJCqP3sNkZcpoSA8bCtGwZ4ASfRLsMFXZDCmMHzCoeJ"
]
}
],
"data": {
"hash": "872fa6e6f46246cd44afdb2ee9cfae0e72885fb0910e2bcf9a5a2a4eadb417b8",
"payload": {
"msg": "Hello BigchainDB!"
}
},
"fulfillments": [
{
"current_owners": [
"3LQ5dTiddXymDhNzETB1rEkp4mA7fEV1Qeiu5ghHiJm9"
],
"fid": 0,
"fulfillment": "cf:1:4:ICKvgXHM8K2jNlKRfkwz3cCvH0OiF5A_-riWsQWXffOMQCyqbFgSDfKTaKRQHypHr5z5jsXzCQ4dKgYkmUo55CMxYs3TT2OxGiV0bZ7Tzn1lcLhpyutGZWm8xIyJKJmmSQQ",
"input": null
}
],
"operation": "CREATE",
"timestamp": "1460450439.267737"
},
"version": 1
}
```
The new owner of the digital asset is now `ssQnnjketNYmbU3hwgFMEQsc4JVYAmZyWHnHCtFS8aeA`, which is the public key of `testuser1`.
The new owner of the digital asset is now `ACJyBLfeLNpCPrGWYoPYvnQ2MAC8BFukBko4hxtW9YoH`, which is the public key of `testuser1`.
## Transfer the Digital Asset
@ -87,10 +122,16 @@ Now that `testuser1` has a digital asset assigned to him, he can transfer it to
```python
# create a second testuser
testuser2_priv, testuser2_pub = b.generate_keys()
testuser2_priv, testuser2_pub = crypto.generate_key_pair()
# retrieve the transaction with condition id
tx_retrieved_id = b.get_owned_ids(testuser1_pub).pop()
{'cid': 0,
'txid': 'cdb6331f26ecec0ee7e67e4d5dcd63734e7f75bbd1ebe40699fc6d2960ae4cb2'}
# create a transfer transaction
tx_transfer = b.create_transaction(testuser1_pub, testuser2_pub, tx_retrieved['id'], 'TRANSFER')
tx_transfer = b.create_transaction(testuser1_pub, testuser2_pub, tx_retrieved_id, 'TRANSFER')
# sign the transaction
tx_transfer_signed = b.sign_transaction(tx_transfer, testuser1_priv)
@ -101,14 +142,47 @@ b.write_transaction(tx_transfer_signed)
# check if the transaction is already in the bigchain
tx_transfer_retrieved = b.get_transaction(tx_transfer_signed['id'])
{ 'id': '1b78c313257540189f27da480152ed8c0b758569cdadd123d9810c057da408c3',
'signature': '3045022056166de447001db8ef024cfa1eecdba4306f92688920ac24325729d5a5068d47022100fbd495077cb1040c48bd7dc050b2515b296ca215cb5ce3369f094928e31955f6',
'transaction': { 'current_owner': 'ssQnnjketNYmbU3hwgFMEQsc4JVYAmZyWHnHCtFS8aeA',
'data': None,
'input': '6539dded9479c47b3c83385ae569ecaa90bcf387240d1ee2ea3ae0f7986aeddd',
'new_owner': 'zVzophT73m4Wvf3f8gFYokddkYe3b9PbaMzobiUK7fmP',
'operation': 'TRANSFER',
'timestamp': '1455109497.480323'}}
{
"id": "86ce10d653c69acf422a6d017a4ccd27168cdcdac99a49e4a38fb5e0d280c579",
"transaction": {
"conditions": [
{
"cid": 0,
"condition": {
"details": {
"bitmask": 32,
"public_key": "7MUjLUFEu12Hk5jb8BZEFgM5JWgSya47SVbqzDqF6ZFQ",
"signature": null,
"type": "fulfillment",
"type_id": 4
},
"uri": "cc:1:20:XmUXkarmpe3n17ITJpi-EFy40qvGZ1C9aWphiiRfjOs:98"
},
"new_owners": [
"7MUjLUFEu12Hk5jb8BZEFgM5JWgSya47SVbqzDqF6ZFQ"
]
}
],
"data": null,
"fulfillments": [
{
"current_owners": [
"DTJCqP3sNkZcpoSA8bCtGwZ4ASfRLsMFXZDCmMHzCoeJ"
],
"fid": 0,
"fulfillment": "cf:1:4:ILkIy_xP7k9clLCaVYtV-8dhuwdebq8yJSjeX1Ln3oUzQPKxMGutQV0EIRYxg81_Z6gdUHQYHkEyTKxwN7zRFjHNAnIdyU1NxqqohhFQSR-qYho-L-uqPRJcAed-SI7xwAI",
"input": {
"cid": 0,
"txid": "cdb6331f26ecec0ee7e67e4d5dcd63734e7f75bbd1ebe40699fc6d2960ae4cb2"
}
}
],
"operation": "TRANSFER",
"timestamp": "1460450449.289641"
},
"version": 1
}
```
## Double Spends
@ -119,12 +193,199 @@ If we try to create another transaction with the same input as before, the trans
```python
# create another transfer transaction with the same input
tx_transfer2 = b.create_transaction(testuser1_pub, testuser2_pub, tx_retrieved['id'], 'TRANSFER')
tx_transfer2 = b.create_transaction(testuser1_pub, testuser2_pub, tx_retrieved_id, 'TRANSFER')
# sign the transaction
tx_transfer_signed2 = b.sign_transaction(tx_transfer2, testuser1_priv)
# check if the transaction is valid
b.validate_transaction(tx_transfer_signed2)
Exception: input `6539dded9479c47b3c83385ae569ecaa90bcf387240d1ee2ea3ae0f7986aeddd` was already spent
DoubleSpend: input `cdb6331f26ecec0ee7e67e4d5dcd63734e7f75bbd1ebe40699fc6d2960ae4cb2` was already spent
```
## Crypto Conditions
### Introduction
### Threshold Signatures
```python
import copy
import json
from cryptoconditions import Ed25519Fulfillment, ThresholdSha256Fulfillment
from bigchaindb import util, crypto
# create some new testusers
thresholduser1_priv, thresholduser1_pub = crypto.generate_key_pair()
thresholduser2_priv, thresholduser2_pub = crypto.generate_key_pair()
# retrieve the last transaction of testuser2
tx_retrieved_id = b.get_owned_ids(testuser2_pub).pop()
# create a base template for a 1-input/2-output transaction
threshold_tx = b.create_transaction(testuser2_pub, [thresholduser1_pub, thresholduser2_pub], tx_retrieved_id, 'TRANSFER')
# create a Threshold Cryptocondition
threshold_condition = ThresholdSha256Fulfillment(threshold=2)
threshold_condition.add_subfulfillment(Ed25519Fulfillment(public_key=thresholduser1_pub))
threshold_condition.add_subfulfillment(Ed25519Fulfillment(public_key=thresholduser2_pub))
# update the condition in the newly created transaction
threshold_tx['transaction']['conditions'][0]['condition'] = {
'details': json.loads(threshold_condition.serialize_json()),
'uri': threshold_condition.condition.serialize_uri()
}
# conditions have been updated, so hash needs updating
threshold_tx_data = copy.deepcopy(threshold_tx)
for fulfillment in threshold_tx_data['transaction']['fulfillments']:
fulfillment['fulfillment'] = None
threshold_tx['id'] = crypto.hash_data(util.serialize(threshold_tx_data['transaction']))
# sign the transaction
threshold_tx_signed = b.sign_transaction(threshold_tx, testuser2_priv)
# write the transaction
b.write_transaction(threshold_tx_signed)
# check if the transaction is already in the bigchain
tx_threshold_retrieved = b.get_transaction(threshold_tx_signed['id'])
{
"id": "f0ea4a96afb3b8cafd6336aa3c4b44d1bb0f2b801f61fcb6a44eea4b870ff2e2",
"transaction": {
"conditions": [
{
"cid": 0,
"condition": {
"details": {
"bitmask": 41,
"subfulfillments": [
{
"bitmask": 32,
"public_key": "3tuSZ4FitNVWRgK7bGe6pEia7ERmxHmhCxFfFEVbD7g4",
"signature": null,
"type": "fulfillment",
"type_id": 4,
"weight": 1
},
{
"bitmask": 32,
"public_key": "8CvrriTsPZULEXTZW2Hnmg7najZsvXzgTi9NKpJaUdHS",
"signature": null,
"type": "fulfillment",
"type_id": 4,
"weight": 1
}
],
"threshold": 2,
"type": "fulfillment",
"type_id": 2
},
"uri": "cc:1:29:kiQHpdEiRe24L62KzwQgLu7dxCHaLBfEFLr_xzlswT4:208"
},
"new_owners": [
"3tuSZ4FitNVWRgK7bGe6pEia7ERmxHmhCxFfFEVbD7g4",
"8CvrriTsPZULEXTZW2Hnmg7najZsvXzgTi9NKpJaUdHS"
]
}
],
"data": null,
"fulfillments": [
{
"current_owners": [
"7MUjLUFEu12Hk5jb8BZEFgM5JWgSya47SVbqzDqF6ZFQ"
],
"fid": 0,
"fulfillment": "cf:1:4:IF5lF5Gq5qXt59eyEyaYvhBcuNKrxmdQvWlqYYokX4zrQDSWz8yxBCFaYFKZOLai5ZCoVq28LVoiQ7TL5zkajG-I-BYH2NaKj7CfPBIZHWkMGWfd_UuQWkbhyx07MJ_1Jww",
"input": {
"cid": 0,
"txid": "86ce10d653c69acf422a6d017a4ccd27168cdcdac99a49e4a38fb5e0d280c579"
}
}
],
"operation": "TRANSFER",
"timestamp": "1460450459.321600"
},
"version": 1
}
```
```python
from cryptoconditions.fulfillment import Fulfillment
thresholduser3_priv, thresholduser3_pub = crypto.generate_key_pair()
# retrieve the last transaction of thresholduser1_pub
tx_retrieved_id = b.get_owned_ids(thresholduser1_pub).pop()
# create a base template for a 2-input/1-output transaction
threshold_tx_transfer = b.create_transaction([thresholduser1_pub, thresholduser2_pub], thresholduser3_pub, tx_retrieved_id, 'TRANSFER')
# parse the threshold cryptocondition
threshold_fulfillment = Fulfillment.from_json(threshold_tx['transaction']['conditions'][0]['condition']['details'])
subfulfillment1 = threshold_fulfillment.subconditions[0]['body']
subfulfillment2 = threshold_fulfillment.subconditions[1]['body']
# get the fulfillment message to sign
threshold_tx_fulfillment_message = util.get_fulfillment_message(threshold_tx_transfer,
threshold_tx_transfer['transaction']['fulfillments'][0])
# sign the subconditions
subfulfillment1.sign(util.serialize(threshold_tx_fulfillment_message), crypto.SigningKey(thresholduser1_priv))
subfulfillment2.sign(util.serialize(threshold_tx_fulfillment_message), crypto.SigningKey(thresholduser2_priv))
threshold_tx_transfer['transaction']['fulfillments'][0]['fulfillment'] = threshold_fulfillment.serialize_uri()
b.write_transaction(threshold_tx_transfer)
{
"id": "27d1e780526e172fdafb6cfec24b43878b0f8a2c34e962546ba4932ef7662646",
"transaction": {
"conditions": [
{
"cid": 0,
"condition": {
"details": {
"bitmask": 32,
"public_key": "4SwVNiYRykGw1ixgKH75k97ipCnmm5QpwNwzQdCKLCzH",
"signature": null,
"type": "fulfillment",
"type_id": 4
},
"uri": "cc:1:20:MzgxMS8Zt2XZrSA_dFk1d64nwUz16knOeKkxc5LyIv4:98"
},
"new_owners": [
"4SwVNiYRykGw1ixgKH75k97ipCnmm5QpwNwzQdCKLCzH"
]
}
],
"data": null,
"fulfillments": [
{
"current_owners": [
"3tuSZ4FitNVWRgK7bGe6pEia7ERmxHmhCxFfFEVbD7g4",
"8CvrriTsPZULEXTZW2Hnmg7najZsvXzgTi9NKpJaUdHS"
],
"fid": 0,
"fulfillment": "cf:1:2:AgIBYwQgKwNKM5oJUhL3lUJ3Xj0dzePTH_1BOxcIry5trRxnNXFANabre0P23pzs3liGozZ-cua3zLZuZIc4UA-2Eb_3oi0zFZKHlL6_PrfxpZFp4Mafsl3Iz1yGVz8s-x5jcbahDwABYwQgaxAYvRMOihIk-M4AZYFB2mlf4XjEqhiOaWpqinOYiXFAuQm7AMeXDs4NCeFI4P6YeL3RqNZqyTr9OsNHZ9JgJLZ2ER1nFpwsLhOt4TJZ01Plon7r7xA2GFKFkw511bRWAQA",
"input": {
"cid": 0,
"txid": "f0ea4a96afb3b8cafd6336aa3c4b44d1bb0f2b801f61fcb6a44eea4b870ff2e2"
}
}
],
"operation": "TRANSFER",
"timestamp": "1460450469.337543"
},
"version": 1
}
```
### Merkle Trees

0
tests/doc/__init__.py Normal file
View File

View File

@ -0,0 +1,133 @@
import copy
import json
from time import sleep
from cryptoconditions import Ed25519Fulfillment, ThresholdSha256Fulfillment
from cryptoconditions.fulfillment import Fulfillment
from bigchaindb import Bigchain, util, crypto, exceptions
b = Bigchain()
# create a test user
testuser1_priv, testuser1_pub = crypto.generate_key_pair()
# define a digital asset data payload
digital_asset_payload = {'msg': 'Hello BigchainDB!'}
# a create transaction uses the operation `CREATE` and has no inputs
tx = b.create_transaction(b.me, testuser1_pub, None, 'CREATE', payload=digital_asset_payload)
# all transactions need to be signed by the user creating the transaction
tx_signed = b.sign_transaction(tx, b.me_private)
# write the transaction to the bigchain
# the transaction will be stored in a backlog where it will be validated,
# included in a block, and written to the bigchain
b.write_transaction(tx_signed)
sleep(10)
tx_retrieved = b.get_transaction(tx_signed['id'])
# create a second testuser
testuser2_priv, testuser2_pub = crypto.generate_key_pair()
# retrieve the transaction with condition id
tx_retrieved_id = b.get_owned_ids(testuser1_pub).pop()
# create a transfer transaction
tx_transfer = b.create_transaction(testuser1_pub, testuser2_pub, tx_retrieved_id, 'TRANSFER')
# sign the transaction
tx_transfer_signed = b.sign_transaction(tx_transfer, testuser1_priv)
# write the transaction
b.write_transaction(tx_transfer_signed)
sleep(10)
# check if the transaction is already in the bigchain
tx_transfer_retrieved = b.get_transaction(tx_transfer_signed['id'])
# create another transfer transaction with the same input
tx_transfer2 = b.create_transaction(testuser1_pub, testuser2_pub, tx_retrieved_id, 'TRANSFER')
# sign the transaction
tx_transfer_signed2 = b.sign_transaction(tx_transfer2, testuser1_priv)
# check if the transaction is valid
try:
b.validate_transaction(tx_transfer_signed2)
except exceptions.DoubleSpend as e:
print(e)
# create some new testusers
thresholduser1_priv, thresholduser1_pub = crypto.generate_key_pair()
thresholduser2_priv, thresholduser2_pub = crypto.generate_key_pair()
# retrieve the last transaction of testuser2
tx_retrieved_id = b.get_owned_ids(testuser2_pub).pop()
# create a base template for a 1-input/2-output transaction
threshold_tx = b.create_transaction(testuser2_pub, [thresholduser1_pub, thresholduser2_pub], tx_retrieved_id, 'TRANSFER')
# create a Threshold Cryptocondition
threshold_condition = ThresholdSha256Fulfillment(threshold=2)
threshold_condition.add_subfulfillment(Ed25519Fulfillment(public_key=thresholduser1_pub))
threshold_condition.add_subfulfillment(Ed25519Fulfillment(public_key=thresholduser2_pub))
# update the condition in the newly created transaction
threshold_tx['transaction']['conditions'][0]['condition'] = {
'details': json.loads(threshold_condition.serialize_json()),
'uri': threshold_condition.condition.serialize_uri()
}
# conditions have been updated, so hash needs updating
threshold_tx_data = copy.deepcopy(threshold_tx)
for fulfillment in threshold_tx_data['transaction']['fulfillments']:
fulfillment['fulfillment'] = None
threshold_tx['id'] = crypto.hash_data(util.serialize(threshold_tx_data['transaction']))
# sign the transaction
threshold_tx_signed = b.sign_transaction(threshold_tx, testuser2_priv)
# write the transaction
b.write_transaction(threshold_tx_signed)
sleep(10)
# check if the transaction is already in the bigchain
tx_threshold_retrieved = b.get_transaction(threshold_tx_signed['id'])
thresholduser3_priv, thresholduser3_pub = crypto.generate_key_pair()
# retrieve the last transaction of thresholduser1_pub
tx_retrieved_id = b.get_owned_ids(thresholduser1_pub).pop()
# create a base template for a 2-input/1-output transaction
threshold_tx_transfer = b.create_transaction([thresholduser1_pub, thresholduser2_pub], thresholduser3_pub, tx_retrieved_id, 'TRANSFER')
# parse the threshold cryptocondition
threshold_fulfillment = Fulfillment.from_json(threshold_tx['transaction']['conditions'][0]['condition']['details'])
subfulfillment1 = threshold_fulfillment.subconditions[0]['body']
subfulfillment2 = threshold_fulfillment.subconditions[1]['body']
# get the fulfillment message to sign
threshold_tx_fulfillment_message = util.get_fulfillment_message(threshold_tx_transfer,
threshold_tx_transfer['transaction']['fulfillments'][0])
# sign the subconditions
subfulfillment1.sign(util.serialize(threshold_tx_fulfillment_message), crypto.SigningKey(thresholduser1_priv))
subfulfillment2.sign(util.serialize(threshold_tx_fulfillment_message), crypto.SigningKey(thresholduser2_priv))
threshold_tx_transfer['transaction']['fulfillments'][0]['fulfillment'] = threshold_fulfillment.serialize_uri()
b.verify_signature(threshold_tx_transfer)
b.validate_transaction(threshold_tx_transfer)
b.write_transaction(threshold_tx_transfer)