diff --git a/routes/baseActionsRouter.js b/routes/baseActionsRouter.js index 656e6a897..a878e035a 100644 --- a/routes/baseActionsRouter.js +++ b/routes/baseActionsRouter.js @@ -831,6 +831,49 @@ function isFlipstarter(tx, fee) { } } +/** + * If transaction is a 'Transaction Input Payload Contract', this returns the + * payload it carries. Otherwise null. + * https://nerdekollektivet.gitlab.io/votepeer-documentation/input-payload-contract/ + */ +function getInputPayloadContractPayload(tx) { + let scriptSig = ""; + try { + scriptSig = tx.vin[0].scriptSig.hex; + scriptAsm = tx.vin[0].scriptSig.asm; + } catch (e) { + // API change? + return null; + } + const redeemscript_regex = /a97ca97e7ca97e21[a-z0-9]{66}76a97b7ea914[a-z0-9]{40}88ad7491$/; + if (!scriptSig.match(redeemscript_regex)) { + return null; + } + try { + const stackElements = scriptAsm.split(' '); + stackElements.pop(); // redeemscript + const push3 = stackElements.pop(); + if (push3 === undefined) return null; + const push2 = stackElements.pop(); + if (push2 === undefined) return null; + const push1 = stackElements.pop(); + if (push1 === undefined) return null; + + let payload = push3; + if (push2 !== '0') { + payload += push2; + } + if (push1 !== '0') { + payload += push1; + } + return payload; + } + catch (e) { + console.log(e); + return null; + } +} + function calcFee(tx, inputTxs) { let inputAmount = new Decimal(0); let outputAmount = new Decimal(0); @@ -875,6 +918,7 @@ router.get("/tx/:transactionId", function(req, res, next) { res.locals.result.txInputs = rawTxResult.txInputsByTransaction[txid] const fee = calcFee(tx, rawTxResult.txInputsByTransaction[txid]); res.locals.result.isflipstarter = isFlipstarter(tx, fee); + res.locals.result.inputPayloadContract = getInputPayloadContractPayload(tx); var promises = []; diff --git a/views/transaction.pug b/views/transaction.pug index cbf41d27d..ecda9d7db 100644 --- a/views/transaction.pug +++ b/views/transaction.pug @@ -235,6 +235,15 @@ block content p Run  a(href=("https://flipstarter.cash")) your own flipstarter crowdfunding campaign. + if (result.inputPayloadContract != null) + p This looks like an  + a(href=("https://nerdekollektivet.gitlab.io/votepeer-documentation/input-payload-contract/")) Input Payload Contract + span  transaction. Input Payload Contract is used to deliver a chunk of arbitrary data on the blockchain. + + p The embedded data is #{result.inputPayloadContract.length} bytes. This is the embedded data: + div.highlight + pre + code.json.bg-light(data-lang="json") "#{result.inputPayloadContract}"