1
0
mirror of https://github.com/bigchaindb/js-bigchaindb-driver.git synced 2024-11-22 09:46:58 +01:00

unique-fulfillment and hash&sign

This commit is contained in:
manolodewiner 2018-03-01 12:22:36 +01:00
parent 428edad6eb
commit c3e1244e52
3 changed files with 27 additions and 17 deletions

View File

@ -18,7 +18,7 @@ before_install:
-e BIGCHAINDB_KEYPAIR_PRIVATE=5C5Cknco7YxBRP9AgB1cbUVTL4FAcooxErLygw1DeG2D -e BIGCHAINDB_KEYPAIR_PRIVATE=5C5Cknco7YxBRP9AgB1cbUVTL4FAcooxErLygw1DeG2D
-e BIGCHAINDB_DATABASE_BACKEND=mongodb -e BIGCHAINDB_DATABASE_BACKEND=mongodb
-e BIGCHAINDB_DATABASE_HOST=172.17.0.1 -e BIGCHAINDB_DATABASE_HOST=172.17.0.1
bigchaindb/bigchaindb:1.3.0 bigchaindb/bigchaindb:1.4.0
start start
- gem install cowsay - gem install cowsay
- npm install -g codecov - npm install -g codecov

View File

@ -30,14 +30,6 @@ export default class Transaction {
} }
} }
static hashTransaction(transaction) {
// Safely remove any tx id from the given transaction for hashing
const tx = { ...transaction }
delete tx.id
return sha256Hash(Transaction.serializeTransactionIntoCanonicalString(tx))
}
static makeTransactionTemplate() { static makeTransactionTemplate() {
const txTemplate = { const txTemplate = {
'id': null, 'id': null,
@ -58,8 +50,6 @@ export default class Transaction {
tx.metadata = metadata tx.metadata = metadata
tx.inputs = inputs tx.inputs = inputs
tx.outputs = outputs tx.outputs = outputs
tx.id = Transaction.hashTransaction(tx)
return tx return tx
} }
@ -246,15 +236,23 @@ export default class Transaction {
signedTx.inputs.forEach((input, index) => { signedTx.inputs.forEach((input, index) => {
const privateKey = privateKeys[index] const privateKey = privateKeys[index]
const privateKeyBuffer = Buffer.from(base58.decode(privateKey)) const privateKeyBuffer = Buffer.from(base58.decode(privateKey))
const serializedTransaction = Transaction const serializedTransaction =
.serializeTransactionIntoCanonicalString(transaction) Transaction.serializeTransactionIntoCanonicalString(transaction)
const transactionUniqueFulfillment = input.fulfills ? serializedTransaction
.concat(input.fulfills.transaction_id)
.concat(input.fulfills.output_index) : serializedTransaction
const transactionHash = sha256Hash(transactionUniqueFulfillment)
const ed25519Fulfillment = new cc.Ed25519Sha256() const ed25519Fulfillment = new cc.Ed25519Sha256()
ed25519Fulfillment.sign(Buffer.from(serializedTransaction), privateKeyBuffer) ed25519Fulfillment.sign(Buffer.from(transactionHash, 'hex'), privateKeyBuffer)
const fulfillmentUri = ed25519Fulfillment.serializeUri() const fulfillmentUri = ed25519Fulfillment.serializeUri()
input.fulfillment = fulfillmentUri input.fulfillment = fulfillmentUri
}) })
const serializedTransaction =
Transaction.serializeTransactionIntoCanonicalString(signedTx)
signedTx.id = sha256Hash(serializedTransaction)
return signedTx return signedTx
} }
} }

View File

@ -1,6 +1,7 @@
import test from 'ava' import test from 'ava'
import cc from 'crypto-conditions' import cc from 'crypto-conditions'
import { Ed25519Keypair, Transaction, ccJsonLoad } from '../../src' import { Ed25519Keypair, Transaction, ccJsonLoad } from '../../src'
import sha256Hash from '../../src/sha256Hash'
test('Ed25519 condition encoding', t => { test('Ed25519 condition encoding', t => {
const publicKey = '4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS' const publicKey = '4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS'
@ -53,16 +54,27 @@ test('Fulfillment correctly formed', t => {
[Transaction.makeOutput(Transaction.makeEd25519Condition(alice.publicKey))], [Transaction.makeOutput(Transaction.makeEd25519Condition(alice.publicKey))],
alice.publicKey alice.publicKey
) )
// Sign in order to get the tx id, needed for the unique fulfillment in the transfer transaction
const signCreateTransaction = Transaction.signTransaction(txCreate, alice.privateKey)
const txTransfer = Transaction.makeTransferTransaction( const txTransfer = Transaction.makeTransferTransaction(
[{ tx: txCreate, output_index: 0 }], [{ tx: signCreateTransaction, output_index: 0 }],
[Transaction.makeOutput(Transaction.makeEd25519Condition(alice.publicKey))], [Transaction.makeOutput(Transaction.makeEd25519Condition(alice.publicKey))],
{} {}
) )
const msg = Transaction.serializeTransactionIntoCanonicalString(txTransfer)
const txSigned = Transaction.signTransaction(txTransfer, alice.privateKey) const txSigned = Transaction.signTransaction(txTransfer, alice.privateKey)
// Here reconstruct the fulfillment of the transfer transaction
// The tx is serialized, and extended with tx_id and output index, and then hashed into bytes
const msg = Transaction.serializeTransactionIntoCanonicalString(txTransfer)
const msgUniqueFulfillment = txTransfer.inputs[0].fulfills ? msg
.concat(txTransfer.inputs[0].fulfills.transaction_id)
.concat(txTransfer.inputs[0].fulfills.output_index) : msg
const msgHash = sha256Hash(msgUniqueFulfillment)
t.truthy(cc.validateFulfillment( t.truthy(cc.validateFulfillment(
txSigned.inputs[0].fulfillment, txCreate.outputs[0].condition.uri, txSigned.inputs[0].fulfillment, txCreate.outputs[0].condition.uri,
Buffer.from(msg) Buffer.from(msgHash, 'hex')
)) ))
}) })