How to testfor what block an arrow ran into

This is my answer for 1.13 snapshots, which you should be using anyway so that your work won't be undone when 1.13 comes out soon! (Commands are pretty much rewritten in 1.13)

What you want to do is get the xTile, yTile, and zTile NBT values of the arrow with NBT of inGround:1b, then teleport an invisible entity (such as a NoAI:1,Invulnerable:1,Silent:1 area_effect_cloud which is commonly used for marking things), and set it to those coordinates. You can do this in the 1.13 snapshots using the execute store and data get commands: execute as @e[type=area_effect_cloud,name=whatever_you_want] store result entity @s Pos[0] double 1 run data get entity @e[type=arrow,limit=1] xTile 1, then do the same for Pos[1] and yTile, and Pos[2] and zTile. Then, have that invisible entity set a block at its location and afterwards kill that entity. Done!

Recap:

  1. If the arrow is in the ground (has NBT inGround:1b), summon an invisible entity as a marker
  2. Set the Pos[] NBT tags of the marker entity as the xTile, yTile, and zTile of the arrow
  3. Have the marker entity set the block at its location to whatever you want
  4. Kill the entity

Sorry for the long explanation, but you can't just have the arrow set a block at it's location because the arrow's position is always outside of the block that it's stuck in.

If you're set on using 1.12, I don't think there's a good way to do this. I couldn't find anything easily on google, but some further searching might turn up something.