4 - 3 使用 JQ

這邊要學會用 JQ 來處理 JSON 資料

用 key 取出在一個 JSON 的某個值

我們用 signrawtransaction 會產生一個 hex 值,我們試著用 JQ 將它取出

基本指令是 jq -r '.'-r 表示輸出原型資料,'.' 表示要輸出什麼

$ bitcoin-cli signrawtransaction $rawtxhex | jq -r '.hex'
0200000001735dfa1584b930a78ad2c1d6db72dd2a80ae5e5d552ad97e19f1d50d41fdd6d8000000006a47304402202210ce4b2a037da02622c380278cd79fec4e0e016e66f3eb894a2dcbb9ee998f02202cac167e6abdbbf08af139fb7c6b86e9d2e58e5516cd566ae2d54953ead9923b012102111bb978a3c93a00038ae344a1a017d7fee8a9be9d0558b5793ce6f440704a96ffffffff01b0e78604000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000

這樣可以取出 hex 值,我們可以進一步將一堆指令變數化,以後方便取用

$ signedtx=$(bitcoin-cli signrawtransaction $rawtxhex | jq -r '.hex')
$ echo $signedtx
0200000001735dfa1584b930a78ad2c1d6db72dd2a80ae5e5d552ad97e19f1d50d41fdd6d8000000006a47304402202210ce4b2a037da02622c380278cd79fec4e0e016e66f3eb894a2dcbb9ee998f02202cac167e6abdbbf08af139fb7c6b86e9d2e58e5516cd566ae2d54953ead9923b012102111bb978a3c93a00038ae344a1a017d7fee8a9be9d0558b5793ce6f440704a96ffffffff01b0e78604000000001976a914e7c1345fc8f87c68170b3aa798a956c2fe6a9eff88ac00000000

可以這樣用

$ bitcoin-cli sendrawtransaction $signedtx
3f9ccb6e16663e66dc119de1866610cc4f7a83079bfec2abf0598ed3adf10a78

Use JQ to Access singel JSON object value in array by key (超難翻譯所以不翻XD)

當我們想要從陣列裡挑出某個項目,例如 listunspent 裡挑出想要的 UTXO,可以這樣做

$ bitcoin-cli listunspent | jq -r '.[0]'
{
  "txid": "03e99644fff32f9d7fc68e1b3253ed1ee9ddc1371c41a0a8e29b1f01ca06f4d9",
  "vout": 0,
  "address": "mrR54buSCnMnf9cBGSrg4zCrWdDnyiQkdM",
  "account": "",
  "scriptPubKey": "76a914778c899d7364cc5c33e5e07d622e31b3798d60f588ac",
  "amount": 1.3,
  "confirmations": 305,
  "spendable": true,
  "solvable": true,
  "safe": true
}

從 UTXO 裡面挑出第一個,在 ' ' 裡面可以繼續的 pipeline,傳遞更多想做的動作,

例如:從某一個 UTXO 裡面挑出 txid

$ bitcoin-cli listunspent | jq -r '.[0] | .txid'
03e99644fff32f9d7fc68e1b3253ed1ee9ddc1371c41a0a8e29b1f01ca06f4d9

如此我們可以創造出很多好用的變數

$ newtxid=$(bitcoin-cli listunspent | jq -r '.[0] | .txid')
$ newvout=$(bitcoin-cli listunspent | jq -r '.[0] | .vout')

Use JQ to access matching JSON object values in an array by key

不只可以列出某一個 UTXO 的某個值,還可以列出所有同個 key 的值,要用的是 '.[]'

$ bitcoin-cli listunsepnt | jq -r '.[] | .amount'

Use JQ for simple caculations by key

現在可以運用 JQ 和 awk 來做數學運算

$ bitcoin-cli listunspent | jq -r '.[] | .amount' | awk '{s+=$1} END {print s}'
//print the total amount output by JQ

也可以挑出 JSON 資料裡的多個值並輸出

$ bitcoin-cli listunspent | jq -r '.[] | .txid, .vout, .amount'
03e99644fff32f9d7fc68e1b3253ed1ee9ddc1371c41a0a8e29b1f01ca06f4d9
0
1.3
3850dd518b8402210eec76ac20230fab6ceb8522d068730ba97247b0b91763e8
0
0.84504001
54bfa8a2e05b087cd3b9c455c95817b87b7f1eb6b9fa7a0c6de29f2a8e36e5ef
0
0.83108164

JQ 也有功能可以美化這些輸出

$ bitcoin-cli listunspent | jq -r '.[] | {txid: .txid, vout: .vout, amount: .amount}'
{
  "txid": "03e99644fff32f9d7fc68e1b3253ed1ee9ddc1371c41a0a8e29b1f01ca06f4d9",
  "vout": 0,
  "amount": 1.3
}
{
  "txid": "3850dd518b8402210eec76ac20230fab6ceb8522d068730ba97247b0b91763e8",
  "vout": 0,
  "amount": 0.84504001
}
{
  "txid": "54bfa8a2e05b087cd3b9c455c95817b87b7f1eb6b9fa7a0c6de29f2a8e36e5ef",
  "vout": 0,
  "amount": 0.83108164
}

現在我們要學會多層的取值,例如從 rawtransaction 裡取得 vin, vout 裡面的東西

其實也很簡單,假設一筆交易有兩個 vin, 兩個 vout,想要取vin值:

$ usedtxid1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[0] | .txid')
$ usedtxid2=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .txid')
$ usedvout1=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .vout')
$ usedvout2=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[1] | .vout')

但好麻煩喔,每次都要打一大串,是不是可以類似像陣列一樣取值呢?可以的

$ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid'))
$ echo ${usedtxid[0]}

($(command)) 意思是將東西存成陣列的意思, ${variable[n]} 是取出第幾個的意思,所以我們可以用陣列的方式取出

現在可以取出某個符合 txid, vout 的 UTXO,運用 select, contains

$ bitcoin-cli listunspent | jq -r '.[] | 
> select (.txid | contains("'${usedtxid[0]}'")) | 
> select(.vout | contsins('${usedvout[0]}'))'
$ bitcoin-cli listunspent | jq -r '.[] | 
> select (.txid | contains("'${usedtxid[1]}'")) | 
> select(.vout | contsins('${usedvout[1]}'))'

上面的指令可以用 for-loop 合併

$ for ((i=0; i<${#usedtxid[*]}; i++); 
> do txid=${usedtxid[i]}; 
> vout=${usedvout[i]}; 
> bitcoin-cli listunspent | jq -r '.[] | select(.txid | contains("'${txid}'")) | select(.vout | contains('${vout}'))'; done;

${#usedtxid[*]} 是取陣列大小

現在可以計算一筆交易的手續費

想法是把一筆交易的 vin 對應的交易的 BTC 數量總和,減掉這筆交易的 vout 的 BTC 數量總和,就是手續費

(一筆交易可以能有多個 vin 、多個 vout)

1. $ usedtxid=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .txid'))
2. $ usedvout=($(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vin | .[] | .vout'))
3. $ btcin=$(for ((i=0; i<${#usedtxid[*]}; i++)); do txid=${usedtxid[i]}; vout=${usedvout[i]}; bitcoin-cli listunspent | jq -r '.[] | select (.txid | contains("'${txid}'")) | select(.vout | contains('$vout')) | .amount'; done | awk '{s+=$1} END {print s}')
4. $ btcout=$(bitcoin-cli decoderawtransaction $rawtxhex | jq -r '.vout  [] | .value' | awk '{s+=$1} END {print s}')
5. $ echo "$btcin-$btcout"| /usr/bin/bc
   .255
  1. 把 vin 的 txid 變數化

  2. 把 vin 的 vout 變數化

  3. 從 UTXO 裡面用 usedtxid, usedtxvout 把交易裡面的 vin 的 BTC 數量加起來

  4. 將交易裡面的 vout 的 BTC 數量加起來

  5. 相減獲得手續費,這邊是將算式導到 bin/bc 讓 linux 計算這個式子

results matching ""

    No results matching ""