]> pere.pagekite.me Git - homepage.git/blobdiff - blog/index.html
Generated.
[homepage.git] / blog / index.html
index b5add74bbc29aba945daebb33b50cb2b20e2079a..d2274f21a28e69c3b052a8b91a8983a423765d61 100644 (file)
 
 
     
+    <div class="entry">
+      <div class="title"><a href="https://people.skolelinux.org/pere/blog/Plain_text_accounting_file_from_your_bitcoin_transactions.html">Plain text accounting file from your bitcoin transactions</a></div>
+      <div class="date"> 7th March 2024</div>
+      <div class="body"><p>A while back I wrote a small script to extract the Bitcoin
+transactions in a wallet in the
+<ahref="https://plaintextaccounting.org/">ledger plain text accounting
+format</a>.  The last few days I spent some time to get it working
+better with more special cases.  In case it can be useful for others,
+here is a copy:</p>
+
+<p><blockquote><pre>
+#!/usr/bin/python3
+#  -*- coding: utf-8 -*-
+#  Copyright (c) 2023-2024 Petter Reinholdtsen
+
+from decimal import Decimal
+import json
+import subprocess
+import time
+
+import numpy
+
+def format_float(num):
+    return numpy.format_float_positional(num, trim='-')
+
+accounts = {
+    u'amount' : 'Assets:BTC:main',
+}
+
+addresses = {
+    '<some address>' : 'Assets:bankkonto',
+    '<some address>' : 'Assets:bankkonto',
+}
+
+def exec_json(cmd):
+    proc = subprocess.Popen(cmd,stdout=subprocess.PIPE)
+    j = json.loads(proc.communicate()[0], parse_float=Decimal)
+    return j
+
+def list_txs():
+    # get all transactions for all accounts / addresses
+    c = 0
+    txs = []
+    txidfee = {}
+    limit=100000
+    cmd = ['bitcoin-cli', 'listtransactions', '*', str(limit)]
+    if True:
+        txs.extend(exec_json(cmd))
+    else:
+        # Useful for debugging
+        with open('transactions.json') as f:
+            txs.extend(json.load(f, parse_float=Decimal))
+    #print txs
+    for tx in sorted(txs, key=lambda a: a['time']):
+#        print tx['category']
+        if 'abandoned' in tx and tx['abandoned']:
+            continue
+        if 'confirmations' in tx and 0 >= tx['confirmations']:
+            continue
+        when = time.strftime('%Y-%m-%d %H:%M', time.localtime(tx['time']))
+        if 'message' in tx:
+            desc = tx['message']
+        elif 'comment' in tx:
+            desc = tx['comment']
+        elif 'label' in tx:
+            desc = tx['label']
+        else:
+            desc = 'n/a'
+        print("%s %s" % (when, desc))
+        if 'address' in tx:
+            print("  ; to bitcoin address %s" % tx['address'])
+        else:
+            print("  ; missing address in transaction, txid=%s" % tx['txid'])
+        print(f"  ; amount={tx['amount']}")
+        if 'fee'in tx:
+            print(f"  ; fee={tx['fee']}")
+        for f in accounts.keys():
+            if f in tx and Decimal(0) != tx[f]:
+                amount = tx[f]
+                print("  %-20s   %s BTC" % (accounts[f], format_float(amount)))
+        if 'fee' in tx and Decimal(0) != tx['fee']:
+            # Make sure to list fee used in several transactions only once.
+            if 'fee' in tx and tx['txid'] in txidfee \
+               and tx['fee'] == txidfee[tx['txid']]:
+                True
+            else:
+                fee = tx['fee']
+                print("  %-20s   %s BTC" % (accounts['amount'], format_float(fee)))
+                print("  %-20s   %s BTC" % ('Expences:BTC-fee', format_float(-fee)))
+                txidfee[tx['txid']] = tx['fee']
+
+        if 'address' in tx and tx['address'] in addresses:
+            print("  %s" % addresses[tx['address']])
+        else:
+            if 'generate' == tx['category']:
+                print("  Income:BTC-mining")
+            else:
+                if amount < Decimal(0):
+                    print(f"  Assets:unknown:sent:update-script-addr-{tx['address']}")
+                else:
+                    print(f"  Assets:unknown:received:update-script-addr-{tx['address']}")
+
+        print()
+        c = c + 1
+    print("# Found %d transactions" % c)
+    if limit == c:
+        print(f"# Warning: Limit {limit} reached, consider increasing limit.")
+
+def main():
+    list_txs()
+
+main()
+</pre></blockquote></p>
+
+<p>It is more of a proof of concept, and I do not expect it to handle
+all edge cases, but it worked for me, and perhaps you can find it
+useful too.</p>
+
+<p>To get a more interesting result, it is useful to map accounts sent
+to or received from to accounting accounts, using the
+<tt>addresses</tt> hash.  As these will be very context dependent, I
+leave out my list to allow each user to fill out their own list of
+accounts.  Out of the box, 'ledger reg BTC:main' should be able to
+show the amount of BTCs present in the wallet at any given time in the
+past.  For other and more valuable analysis, a account plan need to be
+set up in the <tt>addresses</tt> hash.  Here is an example
+transaction:</p>
+
+<p><blockquote><pre>
+2024-03-07 17:00 Donated to good cause
+    Assets:BTC:main                           -0.1 BTC
+    Assets:BTC:main                       -0.00001 BTC
+    Expences:BTC-fee                       0.00001 BTC
+    Expences:donations                         0.1 BTC
+</pre></blockquote></p>
+
+<p>It need a running Bitcoin Core daemon running, as it connect to it
+using <tt>bitcoin-cli listtransactions * 100000</tt> to extract the
+transactions listed in the Wallet.</p>
+
+<p>As usual, if you use Bitcoin and want to show your support of my
+activities, please send Bitcoin donations to my address
+<b><a href="bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b</a></b>.</p>
+</div>
+      <div class="tags">
+        
+        
+        Tags: <a href="https://people.skolelinux.org/pere/blog/tags/bitcoin">bitcoin</a>, <a href="https://people.skolelinux.org/pere/blog/tags/english">english</a>. 
+        
+        
+      </div>
+    </div>
+    <div class="padding"></div>
+    
     <div class="entry">
       <div class="title"><a href="https://people.skolelinux.org/pere/blog/RAID_status_from_LSI_Megaraid_controllers_using_free_software.html">RAID status from LSI Megaraid controllers using free software</a></div>
       <div class="date"> 3rd March 2024</div>
@@ -29,7 +183,7 @@ got my hands on one of these.  I had forgotten how to handle this RAID
 controller in Debian, so I had to take a peek in the
 <a href="https://wiki.debian.org/LinuxRaidForAdmins">Debian wiki page
 "Linux and Hardware RAID: an administrator's summary"</a> to remember
-that kind of software is available to configure and monitor the disks
+what kind of software is available to configure and monitor the disks
 and controller.  I prefer Free Software alternatives to proprietary
 tools, as the later tend to fall into disarray once the manufacturer
 loose interest, and often do not work with newer Linux Distributions.
@@ -1524,65 +1678,6 @@ betaling med bitcoin er ikke anonymt. :)</p>
     </div>
     <div class="padding"></div>
     
-    <div class="entry">
-      <div class="title"><a href="https://people.skolelinux.org/pere/blog/_underordnet_tjenestemann_blir_inhabil_fordi_en_overordnet_er_inhabil__.html">«underordnet tjenestemann blir inhabil fordi en overordnet er inhabil».</a></div>
-      <div class="date"> 7th September 2023</div>
-      <div class="body"><p>Medlemmene av Norges regjering har demonstert de siste månedene at
-habilitetsvureringer ikke er deres sterke side og det gjelder både
-Arbeiderpartiets og Senterpartiers representater. Det er heldigvis
-enklere i det private, da inhabilitetsreglene kun gjelder de som
-jobber for folket, ikke seg selv.  Sist ut er utenriksminister
-Huitfeldt.  I går kom nyheten om at
-<a href="https://www.nrk.no/nyheter/riksadvokaten_-okokrim-nestsjef-kan-behandle-huitfeldt-saken-1.16545162">Riksadvokaten
-har konkludert med at nestsjefen i Økokrim kan behandle sak om
-habilitet og innsidekunnskap</a> for Huitfeldt, på tross av at hans
-overordnede, sjefen for Økokrim, har meldt seg inhabil i saken.  Dette
-er litt rart.  I veilednigen
-«<a href="https://www.regjeringen.no/globalassets/upload/krd/vedlegg/komm/veiledere/habilitet_i_kommuner_og_fylkeskommuner.pdf">Habilitet
-i kommuner og fylkeskommuner</a>» av Kommunal- og regionaldepartementet
-forteller de hva som gjelder, riktig nok gjelder veiledningen ikke for
-Økokrim som jo ikke er kommune eller fylkeskommune, men jeg får ikke
-inntrykk av at dette er regler som kun gjelder for kommune og
-fylkeskommune:
-
-<blockquote>
-<p>«<strong>2.1 Oversikt over inhabilitetsgrunnlagene</strong>
-
-<p>De alminnelige reglene om inhabilitet for den offentlige
-forvaltningen er gitt i
-<a href="https://lovdata.no/dokument/NL/lov/1967-02-10/KAPITTEL_2#KAPITTEL_2">forvaltningsloven
-§§ 6 til 10</a>. Forvaltningslovens hovedregel om inhabilitet framgår
-av § 6. Her er det gitt tre ulike grunnlag som kan føre til at en
-tjenestemann eller folkevalgt blir inhabil. I § 6 første ledd
-bokstavene a til e er det oppstilt konkrete tilknytningsforhold mellom
-tjenestemannen og saken eller sakens parter som automatisk fører til
-inhabilitet. Annet ledd oppstiller en skjønnsmessig regel om at
-tjenestemannen også kan bli inhabil etter en konkret vurdering av
-inhabilitetsspørsmålet, der en lang rekke momenter kan være
-relevante. I tredje ledd er det regler om såkalt avledet
-inhabilitet. Det vil si at en underordnet tjenestemann blir inhabil
-fordi en overordnet er inhabil.»</p>
-</blockquote>
-
-<p>Loven sier ganske enkelt «Er den overordnede tjenestemann ugild,
-kan avgjørelse i saken heller ikke treffes av en direkte underordnet
-tjenestemann i samme forvaltningsorgan.»  Jeg antar tanken er at en
-underordnet vil stå i fare for å tilpasse sine konklusjoner til det
-overordnet vil ha fordel av, for å fortsatt ha et godt forhold til sin
-overordnede.  Men jeg er ikke jurist og forstår nok ikke kompliserte
-juridiske vurderinger.  For å sitere «Kamerat Napoleon» av George
-Orwell: «Alle dyr er like, men noen dyr er likere enn andre».
-</div>
-      <div class="tags">
-        
-        
-        Tags: <a href="https://people.skolelinux.org/pere/blog/tags/norsk">norsk</a>. 
-        
-        
-      </div>
-    </div>
-    <div class="padding"></div>
-    
     <p style="text-align: right;"><a href="index.rss"><img src="https://people.skolelinux.org/pere/blog/xml.gif" alt="RSS feed" width="36" height="14" /></a></p>
     <div id="sidebar">
       
@@ -1598,7 +1693,7 @@ Orwell: «Alle dyr er like, men noen dyr er likere enn andre».
 
 <li><a href="https://people.skolelinux.org/pere/blog/archive/2024/02/">February (1)</a></li>
 
-<li><a href="https://people.skolelinux.org/pere/blog/archive/2024/03/">March (1)</a></li>
+<li><a href="https://people.skolelinux.org/pere/blog/archive/2024/03/">March (2)</a></li>
 
 </ul></li>
 
@@ -2031,7 +2126,7 @@ Orwell: «Alle dyr er like, men noen dyr er likere enn andre».
 
  <li><a href="https://people.skolelinux.org/pere/blog/tags/betalkontant">betalkontant (9)</a></li>
 
- <li><a href="https://people.skolelinux.org/pere/blog/tags/bitcoin">bitcoin (12)</a></li>
+ <li><a href="https://people.skolelinux.org/pere/blog/tags/bitcoin">bitcoin (13)</a></li>
 
  <li><a href="https://people.skolelinux.org/pere/blog/tags/bootsystem">bootsystem (17)</a></li>
 
@@ -2053,7 +2148,7 @@ Orwell: «Alle dyr er like, men noen dyr er likere enn andre».
 
  <li><a href="https://people.skolelinux.org/pere/blog/tags/drivstoffpriser">drivstoffpriser (4)</a></li>
 
- <li><a href="https://people.skolelinux.org/pere/blog/tags/english">english (457)</a></li>
+ <li><a href="https://people.skolelinux.org/pere/blog/tags/english">english (458)</a></li>
 
  <li><a href="https://people.skolelinux.org/pere/blog/tags/fiksgatami">fiksgatami (23)</a></li>