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_DATABASE_BACKEND=mongodb
-e BIGCHAINDB_DATABASE_HOST=172.17.0.1
bigchaindb/bigchaindb:1.3.0
bigchaindb/bigchaindb:1.4.0
start
- gem install cowsay
- 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() {
const txTemplate = {
'id': null,
@ -58,8 +50,6 @@ export default class Transaction {
tx.metadata = metadata
tx.inputs = inputs
tx.outputs = outputs
tx.id = Transaction.hashTransaction(tx)
return tx
}
@ -246,15 +236,23 @@ export default class Transaction {
signedTx.inputs.forEach((input, index) => {
const privateKey = privateKeys[index]
const privateKeyBuffer = Buffer.from(base58.decode(privateKey))
const serializedTransaction = Transaction
.serializeTransactionIntoCanonicalString(transaction)
const serializedTransaction =
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()
ed25519Fulfillment.sign(Buffer.from(serializedTransaction), privateKeyBuffer)
ed25519Fulfillment.sign(Buffer.from(transactionHash, 'hex'), privateKeyBuffer)
const fulfillmentUri = ed25519Fulfillment.serializeUri()
input.fulfillment = fulfillmentUri
})
const serializedTransaction =
Transaction.serializeTransactionIntoCanonicalString(signedTx)
signedTx.id = sha256Hash(serializedTransaction)
return signedTx
}
}

View File

@ -1,6 +1,7 @@
import test from 'ava'
import cc from 'crypto-conditions'
import { Ed25519Keypair, Transaction, ccJsonLoad } from '../../src'
import sha256Hash from '../../src/sha256Hash'
test('Ed25519 condition encoding', t => {
const publicKey = '4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS'
@ -53,16 +54,27 @@ test('Fulfillment correctly formed', t => {
[Transaction.makeOutput(Transaction.makeEd25519Condition(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(
[{ tx: txCreate, output_index: 0 }],
[{ tx: signCreateTransaction, output_index: 0 }],
[Transaction.makeOutput(Transaction.makeEd25519Condition(alice.publicKey))],
{}
)
const msg = Transaction.serializeTransactionIntoCanonicalString(txTransfer)
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(
txSigned.inputs[0].fulfillment, txCreate.outputs[0].condition.uri,
Buffer.from(msg)
Buffer.from(msgHash, 'hex')
))
})