Add asset create and transfer

This commit is contained in:
vrde 2016-02-24 02:38:30 +01:00
parent 445bacce0d
commit aeede79846
8 changed files with 92 additions and 10 deletions

View File

@ -96,7 +96,7 @@ class Bigchain(object):
public_key = crypto.PublicKey(public_key_base58) public_key = crypto.PublicKey(public_key_base58)
return public_key.verify(util.serialize(data), signature) return public_key.verify(util.serialize(data), signature)
def write_transaction(self, signed_transaction): def write_transaction(self, signed_transaction, durability='soft'):
"""Write the transaction to bigchain. """Write the transaction to bigchain.
When first writing a transaction to the bigchain the transaction will be kept in a backlog until When first writing a transaction to the bigchain the transaction will be kept in a backlog until
@ -122,7 +122,7 @@ class Bigchain(object):
signed_transaction.update({'assignee': assignee}) signed_transaction.update({'assignee': assignee})
# write to the backlog # write to the backlog
response = r.table('backlog').insert(signed_transaction, durability='soft').run(self.conn) response = r.table('backlog').insert(signed_transaction, durability=durability).run(self.conn)
return response return response
# TODO: the same `txid` can be in two different blocks # TODO: the same `txid` can be in two different blocks

View File

@ -5,6 +5,7 @@ import time
import multiprocessing as mp import multiprocessing as mp
from datetime import datetime from datetime import datetime
import bigchaindb
from bigchaindb import exceptions from bigchaindb import exceptions
from bigchaindb.crypto import PrivateKey, PublicKey from bigchaindb.crypto import PrivateKey, PublicKey
@ -154,7 +155,7 @@ def sign_tx(transaction, private_key):
def create_and_sign_tx(private_key, current_owner, new_owner, tx_input, operation='TRANSFER', payload=None): def create_and_sign_tx(private_key, current_owner, new_owner, tx_input, operation='TRANSFER', payload=None):
tx = create_tx(current_owner, new_owner, tx_input, operation, payload) tx = create_tx(current_owner, new_owner, tx_input, operation, payload)
return sign_tx(private_key, tx) return sign_tx(tx, private_key)
def hash_data(data): def hash_data(data):
@ -195,3 +196,17 @@ def verify_signature(signed_transaction):
public_key = PublicKey(public_key_base58) public_key = PublicKey(public_key_base58)
return public_key.verify(serialize(data), signature) return public_key.verify(serialize(data), signature)
def transform_create(tx):
"""Change the owner and signature for a ``CREATE`` transaction created by a node"""
# XXX: the next instruction opens a new connection to the DB, consider using a singleton or a global
# if you need a Bigchain instance.
b = bigchaindb.Bigchain()
transaction = tx['transaction']
payload = None
if transaction['data'] and 'payload' in transaction['data']:
payload = transaction['data']['payload']
new_tx = create_tx(b.me, transaction['current_owner'], None, 'CREATE', payload=payload)
return new_tx

View File

@ -1,13 +1,32 @@
import flask import flask
from flask import Blueprint from flask import request, Blueprint
from bigchaindb import util
from bigchaindb import Bigchain from bigchaindb import Bigchain
basic_views = Blueprint('basic_views', __name__) basic_views = Blueprint('basic_views', __name__)
b = Bigchain() b = Bigchain()
@basic_views.route('/tx/<tx_id>') @basic_views.route('/tx/<tx_id>')
def show(tx_id): def get_transaction(tx_id):
tx = b.get_transaction(tx_id) tx = b.get_transaction(tx_id)
return flask.jsonify(**tx) return flask.jsonify(**tx)
@basic_views.route('/tx/', methods=['POST'])
def create_transaction():
val = {}
tx = request.get_json(force=True)
if tx['operation'] == 'CREATE':
tx = util.transform_create(tx)
tx = util.sign_tx(tx, b.me_private)
if not util.verify_signature(tx):
val['error'] = 'Invalid transaction signature'
val = b.write_transaction(tx)
return flask.jsonify(**tx)

View File

@ -47,3 +47,10 @@ def user_private_key():
@pytest.fixture @pytest.fixture
def user_public_key(): def user_public_key():
return USER_PUBLIC_KEY return USER_PUBLIC_KEY
@pytest.fixture
def b():
from bigchaindb import Bigchain
return Bigchain()

View File

@ -80,10 +80,6 @@ def cleanup_tables(request, node_config):
request.addfinalizer(fin) request.addfinalizer(fin)
@pytest.fixture
def b():
return Bigchain()
@pytest.fixture @pytest.fixture
def inputs(user_public_key, amount=1, b=None): def inputs(user_public_key, amount=1, b=None):
# 1. create the genesis block # 1. create the genesis block

View File

@ -4,6 +4,7 @@ import pytest
import rethinkdb as r import rethinkdb as r
import bigchaindb import bigchaindb
from bigchaindb import util
from bigchaindb.db import utils from bigchaindb.db import utils
from .conftest import setup_database as _setup_database from .conftest import setup_database as _setup_database

12
tests/test_util.py Normal file
View File

@ -0,0 +1,12 @@
from bigchaindb import util
def test_transform_create(b, user_private_key, user_public_key):
tx = util.create_tx(user_public_key, user_public_key, None, 'CREATE')
tx = util.transform_create(tx)
tx = util.sign_tx(tx, b.me_private)
assert tx['transaction']['current_owner'] == b.me
assert tx['transaction']['new_owner'] == user_public_key
assert util.verify_signature(tx)

View File

@ -1,10 +1,42 @@
import json
import pytest import pytest
from bigchaindb import crypto
from bigchaindb import util
@pytest.mark.usefixtures('inputs') @pytest.mark.usefixtures('inputs')
def test_tx_endpoint(b, client, user_public_key): def test_get_transaction_endpoint(b, client, user_public_key):
input_tx = b.get_owned_ids(user_public_key).pop() input_tx = b.get_owned_ids(user_public_key).pop()
tx = b.get_transaction(input_tx) tx = b.get_transaction(input_tx)
res = client.get('/tx/{}'.format(input_tx)) res = client.get('/tx/{}'.format(input_tx))
assert tx == res.json assert tx == res.json
def test_post_create_transaction_endpoint(b, client):
keypair = crypto.generate_key_pair()
tx = util.create_and_sign_tx(keypair[0], keypair[1], keypair[1], None, 'CREATE')
res = client.post('/tx/', data=json.dumps(tx))
from pprint import pprint as pp
pp(res.body)
assert res.json['transaction']['current_owner'] == b.me
assert res.json['transaction']['new_owner'] == keypair[1]
def test_post_transfer_transaction_endpoint(b, client):
from_keypair = crypto.generate_key_pair()
to_keypair = crypto.generate_key_pair()
tx = util.create_and_sign_tx(from_keypair[0], from_keypair[1], from_keypair[1], None, 'CREATE')
res = client.post('/tx/', data=json.dumps(tx))
tx_id = res.json['id']
transfer = util.create_and_sign_tx(from_keypair[0], from_keypair[1], to_keypair[1], tx_id)
res = client.post('/tx/', data=json.dumps(transfer))
assert res.json['transaction']['current_owner'] == from_keypair[1]
assert res.json['transaction']['new_owner'] == to_keypair[1]