const EmRePayload = require('./er_payload')
const { EMRE_NAMESPACE, EMRE_FAMILY, EmReState } = require('./er_state')
const { TransactionHandler } = require('sawtooth-sdk/processor/handler')
const { InvalidTransaction } = require('sawtooth-sdk/processor/exceptions')
class EMREHandler extends TransactionHandler {
super(EMRE_FAMILY, ['1.0'], [EMRE_NAMESPACE])
apply(transactionProcessRequest, context) {
let payload = EmRePayload.fromBytes(transactionProcessRequest.payload)
let emreState = new EmReState(context)
let header = transactionProcessRequest.header
let by = header.signerPublicKey
if (payload.action === 'create') {
return emreState.getdRec(payload.name)
if (dRec !== undefined) {
throw new InvalidTransaction('Invalid Action: dRec already exists.')
let Allowed = isAllowed(payload.desc)
function isAllowed(str) {
return /[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\,\.\-_\^\@\$\%\*\(\)\=\+\/]/.test(str);
throw new InvalidTransaction('Invalid Description: Only "Aa-Zz-_,.^@$%+/=" allowed in description.')
let createddRec = { //addressing records by their contents can ensure everybody signs the same records.
name: payload.desc.country + payload.desc.last_reported_year + payload.desc.last_reported_mmtco2e + payload.desc.gas_type,
t: payload.desc.gas_type,
y: payload.desc.last_reported_year,
r: payload.desc.last_reported_mmtco2e,
d: payload.desc.data_source,
p: payload.desc.data_reporter_public_key,
i: payload.desc.ipfs_identity,
return emreState.setdRec(payload.name, createddRec)
} else if (payload.action === 'veri') {
return emreState.getdRec(payload.name)
if (dRec === undefined) {
throw new InvalidTransaction(
'Invalid Action: Verify requires an existing dRec.'
for (i = 0; i < dRec.veri.length; i++) {
if (by === dRec.veri[i][0]) {
if (by !== dRec.by && !veri) {
return emreState.setdRec(payload.name, dRec)
} else if (payload.action === 'fix') {
return emreState.getdRec(payload.name)
if (dRec === undefined) {
throw new InvalidTransaction(
'Invalid Action: Verify requires an existing dRec.'
for (i = 0; i < dRec.veri.length; i++) {
if (by === dRec.veri[i][0]) {
if (by !== dRec.by && !veri) {
dRec.veri.push([by, payload.desc])
return emreState.setdRec(payload.name, dRec)
} else if (payload.action === 'delete') {
return emreState.getdRec(payload.name)
if (dRec === undefined) {
throw new InvalidTransaction(
`No dRec exists with name ${payload.name}: unable to delete`)
} else if (by == dRec.by) {
return emreState.deletedRec(payload.name)
for (i = 0; i < arr.length; i++) {
dRec.veri.splice(index, 1)
return emreState.setdRec(payload.name, dRec)
throw new InvalidTransaction(
`You don't have permission to do that.`)
throw new InvalidTransaction(
`Action must be create, delete, or veri not ${payload.action}`
module.exports = EMREHandler