[PeerAssets challenge] #2 Decode card issue txn (200PPC to win)

Hi all, I’m back with two new PeerAssets challenges, each with a bounty of 100PPC.

On peercoin’s testnet, the first card issue transaction has taken place!
You can find this card issue transaction by it’s id: 39b46de5f651ee9a6b50d62bee1f5cd3cb9e1169bf59418b38e1fc1b3ce0e529

Here is the raw transaction for people without a testnet client:


Solve one of the challenges below, explain how you solved it and the address to send the bounty to.
The bounty is paid to the first one to solve and explain correctly how the challenge is solved.

Challenge 1 (100PPC): Which asset is issued by this card issue transaction? And explain. Solved by @thehuntergames: https://www.peercointalk.org/index.php?topic=4789.msg45263#msg45263
Hint: P2TH related, no protobuf parsing required.

Challenge 2 (100PPC): Who got it issued to? Provide the address(es), amount(s) and explain. Solved by @Nagalim: https://www.peercointalk.org/index.php?topic=4789.msg45256#msg45256
Hint: requires parsing the protobuf message to get all information (can be partially solved without it)

Extra challenge: 100PPC reward for the first reported bug (decent bug)

Expiration: This challenge runs until the card issue transaction parsing is deployed in Mercator: (a few weeks from now)

Hint: use https://github.com/PeerAssets/peerassets.js or base yourself on https://github.com/PeerAssets/rnc

Brought to you by PeerScript labs: https://hrobeers.github.io/peerscript-labs/

I will match the challenges. Make it 200 ppc for each

address: PJ1e87QLfHFrqCFSkYtkKygnWwGVbLTWKB
amount: 4.90000000

I had no clou so I googled “raw transaction address amount” and went here: https://en.bitcoin.it/wiki/Raw_Transactions#createrawtransaction_.5B.7B.22txid.22:txid.2C.22vout.22:n.7D.2C…5D_.7Baddress:amount.2C…7D

“decoderawtransaction” command in Peerunity debug window brought this:

“value” : 4.90000000,
“n” : 5,
“scriptPubKey” : {
“asm” : “OP_DUP OP_HASH160 6759a0764127ae9047bff989f330bc2c5d0cfa1e OP_EQUALVERIFY OP_CHECKSIG”,
“hex” : “76a9146759a0764127ae9047bff989f330bc2c5d0cfa1e88ac”,
“reqSigs” : 1,
“type” : “pubkeyhash”,
“addresses” : [

(and some other addresses with zero value)

Marloon is incorrect, he is using mainnet not testnet (testnet addresses begin with n and m) and the dust outputs totally matter. I’m still working on it, I’m getting stuck up on the protobuf3 stuff.

You are indeed incorrect, but I will allow mainnet encoded addresses, no worry. I’m able to convert them :wink:

The output you selected is the PPC change output. It is an output to return the unused PPC to the sender, it has no meaning for the PeerAssets transaction.

Challenge 2 indeed requires parsing the protobuf.

Challenge 1 only needs to figure out the P2TH output.

I’ll add this hints to the first post.

Great to see this activity :slight_smile:

Also great thanks to @SLKRD to double the rewards!

You sent:
Amount: 1.72910^-4
Amount: 7.12
Amount: 9.87*10^-5

V[0] is the tag, V[1] is the OP_RETURN of 1206c102c803db07. The other V[n] are destinations.
The first 2 digits are version number, then 3 repeated amounts, followed by a number of decimals.
So the amounts are:
in hexidecimal.
There are 7 decimal places.

My question is how do I differentiate between a destination address and the change address? Does there always need to be a change address, even if it’s a zero output? So I can’t do other independent ppc outputs with the same txn?

here is an idea:

you start with importing these 2 priv keys on testnet:


both lists all spaws of P2TH tags

vout[0] gives you which P2TH tag you should look for

vout[1]: (OP_RETURN) of the spawn transaction contains a protobuf message which contains Short name for the registered asset
the name itself can be easily decoded with a simple hex to string like http://string-functions.com/hex-string.aspx

The receiver addresses are correct! But the amounts are wrong.

No there doesn’t need to be a change output. After the specified outputs, you can include as many ppc outputs as you like. The number of receiving outputs is defined somewhere in the protobuf message.

Won’t work, the protobuf does not contain the shortname, would be duplication of information and there is no requirement for a shortname to be unique.

Ok, it’s a packed repeated field, where the ‘06’ refers to the 6 following bytes. There is no decimal number, implying 1 is the smallest share.
So the amounts are:
Hex: c102
Dec: 49410
Hex: c803
Dec: 51203
Hex: db07
Dec: 56071

Almost there :slight_smile:
But they are encoded as unsigned varint.

I’m impressed by your perseverance of decoding the message by hand, but you can also just use the protobuf definition and decode it programmatically: https://github.com/PeerAssets/rnc/blob/master/0001-peerassets-transaction-specification.proto

Or you can use the the JS implementation: https://github.com/PeerAssets/peerassets.js
which has a function called: “decodeCardTransferTransaction” :wink:

ok guys, this hint should get you guys to the solution.
You can use the peerassets.js code by browsing to the peerscript-labs page and opening the console (CTRL+SHIFT+I).

In that console, you should require the libs to use.
Execute the following lines in the console:

Transaction = require('bitcore-lib').Transaction
PeerAssets = require('lib/peerassets/peerassets')

Your browser should look similar to this:

now you can parse a raw transaction like this:

txn = new Transaction(<raw-txn-string>)

and you can access the peerassets.js functions through the PeerAssets object.


taking c102 = 1100 0001 0000 0010
Then switch the bytes, cause varint does lowest sig digit first:
0000 0010 1100 0001
Drop the starting bit of each byte cause it’s an indicator:
000 0010 100 0001
10 100 0001
This equals 321 in decimal.

We have a winner for challenge 2!
Please post an address for the rewards, so me and @SLKRD can send you each 100PPC!

Challenge 1 is still open!



my testnet is up to date now

importprivkey cTJVuFKuupqVjaQCFLtsJfG8NyEyHZ3vjCdistzitsD2ZapvwYZH PAprod

at the moment there are 2 deck spawns, one of which is transactionid 93dff… on 11/29/2016

which happens to be vin[0] in the decoded transaction

getrawtransaction 93dff…
decoderawtransaction of the above
gives you the desk spawn transaction.

The vout[1]: (OP_RETURN) of this is 0801112…

Not sure what you want to know but the short name is indeed not unique but it is My little pony. the txid is unqique tho

According to Mercator, there is only one valid deck spawn on PA prod:
The other one is probably not a valid deck spawn, will check it later.

Unfortunately your reasoning is incorrect. As you can see on the Mercator page, there are two deck spawned from mpwRGC6URPCvdU4J83YbUzvqmBhKSDXk4p
One on PAprod (My little pony): 93dff38d65ef25ff9539ea2fa1fda45eb29d8bb989ca91399218c7e83e6630ea
One on PAtest (hello): 388838106ad9970e238a52db448dc2ab630d9b1ff547b8fa56b8713bb9ff9ff5

The card issue transaction is linked to one of these two.
For this the P2TH of the card issue transaction should be used, not the P2TH of the deck spawn.

You’re getting close, but you aren’t there yet :wink:

Reward is transferred!


yes thanks, wrong reasoning:

vout[0] is the P2TH address: mxzUgsizvdifcYHEDdZmro3bCRJzwvDGg4

why My little pony is the asset is because the P2TH(tx) is mxzUgsizvdifcYHEDdZmro3bCRJzwvDGg4

bc = require(‘bitcore-lib’)
testnet = bc.Networks.get( ‘peercoin-testnet’);

var binaryTxnId = Buffer.from(‘93dff38d65ef25ff9539ea2fa1fda45eb29d8bb989ca91399218c7e83e6630ea’, ‘hex’);

bn = bc.crypto.BN.fromBuffer(binaryTxnId)
Object { sign: false, words: Array[11], length: 10, red: null }
priv = bc.PrivateKey.fromBuffer(bn, testnet)
Object { bn: Object, compressed: true, network: Object, publicKey: Getter }

And since this is a card issue transaction, this is sent from the spawning address