Bitcoin Forum
December 04, 2023, 07:01:26 PM *
News: Latest Bitcoin Core release: 25.0 [Torrent]
 
  Home Help Search Login Register More  
  Show Posts
Pages: [1] 2 »
1  Local / Off-Topic (Deutsch) / Corona-Umfrage: Wie hat Deutschland auf Corona reagiert? on: May 05, 2020, 08:07:56 PM
Bin gespannt ...
2  Local / Presse / [2020-04-30] Telepolis: Der Bitcoin on: April 30, 2020, 07:12:38 PM
https://www.heise.de/tp/features/Der-Bitcoin-4711395.html
3  Local / Presse / heise.de: Fidor Bank: Datenleck enthüllte fremde Überweisungsdaten on: April 17, 2020, 12:21:44 PM
https://www.heise.de/security/meldung/Fidor-Bank-Datenleck-enthuellte-fremde-Ueberweisungsdaten-4703740.html
4  Local / Anfänger und Hilfe / [Howto] Two-Factor-Authentication auf dem eigenen Server on: February 08, 2020, 12:33:36 PM
Anbei eine Anleitung wie man 2FA auf einem Linux-Server einrichtet (getestet auf Raspbian Strech und Buster). Teilweise noch unvollständig.

Einleitung
Voraussetzungen
Einrichtung von google-authenticator auf dem Zweitgerät
Einrichtung von google-authenticator auf dem Server
Bermerkungen zu verschlüsselten Daten
Referenzen

Einleitung

Alle, die auf Börsen unterwegs sind, wissen das zusätzliche Sicherheitsfeature 2FA zu schätzen. Diese Methode stellt eine zusätzliche Hürde für die Übernahme eines Accounts dar, da ein simples Abfangen/Erraten/Erhacken des Login-Passworts für diesen Zweck nicht mehr ausreicht. Essenziell hierfür ist, dass die nutzerseitige 2FA-generierende Software auf einem Zweitgerät läuft.

Ein paar Definitionen und Erklärungen:
  • 2FA: Two-Factor-Authentication.
  • Server: Z.B. Börse mit Webinterface fürs Login oder ein Raspi mit ssh-Zugang per Konsole.
  • Account: Z.B. Nutzeraccount bei einer Börse oder direkt auf einem Server.
  • Erstgerät:
    • Das Gerät mit welchem man den normalen Login-Vorgang durchführt.
    • In der Regel ein PC.
  • Zweitgerät:
    • Das Gerät, welches die 2FA-Token für den Login-Vorgang generiert.
    • In der Regel ein Smartphone.
    • Zweitgerät MUSS UNGLEICH Erstgerät sein damit das Prinzip greift.
  • 2FA-Masterkey:
    • Die Seed für die Erzeugen der 2FA-Token.
    • Besteht in der Regel aus einem kryptischen String.
    • Dieser liegt auf dem Server und auf dem Zweitgerät.
    • Es handelt sich hierbei um symmetrische Kryptographie (zumindest wenn man oath-tool nutzt: https://www.nongnu.org/oath-toolkit/), es ist aber nicht ausgeschlossen, dass es andere Methoden gibt.
  • 2FA-Token:
    • In der Regel eine sechstellige Zahl, welche sich alle 30 Sekunden ändert.
    • Diese Zahl hängt deterministisch vom 2FA-Masterkey und der aktuellen Zeit ab.
    • Wird beim Login am Server zusätzlich zum Passwort eingegeben.
    • Voraussetzung für einen erfolgreichen Login ist, dass die Uhren auf Server und Zweitgerät korrekt synchronisiert sind.
    • Wer Zugriff auf die Hardware des Servers hat, hat somit auch Zugriff auf den Masterkey.
  • Verification Code (VC): Muss einmalig zur Aktivierung von 2FA auf dem Server eingegeben werden, siehe weiter unten.

Z.B. ist so die Übernahme eines Accounts nur per Login-Passwort nicht mehr möglich! Wer seine Passwörter mal irgendwo hat rumliegen lassen oder wem diese wie auch immer gestohlen wurden, ist per 2FA trotzdem noch geschützt. Wer einen Keylogger u.ä. auf seinem Rechner laufen hat, ist durch 2FA sicherer, denn der Angreifer müsste zusätzlich das 2FA-Token abfangen um selbst, vor dem eigentlich Accountbesitzer, den Login durchzuführen. Ist natürlich auch der 2FA-Masterkey dem Angreifer bekannt, ist der Account für den eigentlichen Besitzer verloren.

Wer nun  einen Server aufsetzt, welcher direkt mit dem Internet kommuniziert, wird oft auch einen SSH-Zugang offenhalten, damit man Zugriff auf den Server hat, wenn die Hardware selbst eine halbe Welt entfernt ist. Das mag der Fall sein, wenn man z.B. selbst auf Reisen ist, oder wenn man den Server in der Cloud laufen hat.

Voraussetzungen

In diesem Howto verwende ich einen Raspberry Pi. Welche Generation, d.h. ob 1, 2, 3 oder 4 ist relativ egal, wichtig ist nur, dass ihr die richtige Raspbian-Version für die gegebene Hardware nutzt. Getestet habe ich das auf einem 1er- und einem 3er-Raspi. Für eine Basisinstallation verweise ich auf:

https://bitcointalk.org/index.php?topic=5202173.0

Und dort im Besonderen auf die zwei Punkte "Vorbereitung der SD-Karte" (https://bitcointalk.org/index.php?topic=5202173.0#post_vorbereitung_sd) und "Konfiguration des Raspi" (https://bitcointalk.org/index.php?topic=5202173.0#post_konfiguration_raspi).

Einrichtung von google-authenticator auf dem Zweitgerät

Ihr benötigt die google-authenticator-App aus dem entsprechenden Playstore um diese auf z.B. eurem Smartphone zu installieren. Diese gibt es für Android auf jeden Fall (https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=de) und auch für iPhones sollte diese zur Verfügung stehen.

Einrichtung von google-authenticator auf dem Server

Per ssh verbinden wir uns mit dem Server:

Code:
ssh thorsten@192.168.178.101

und installieren den google-authenticator:

Code:
sudo apt-get install libpam-google-authenticator

Dann editieren wir die erste ssh-Konfigurationsdatei:

Code:
sudo nano /etc/pam.d/sshd

und fügen folgende Zeile unten in der Datei ein:

Code:
auth required pam_google_authenticator.so

Wir speichern die Datei via Strg+x. Nun editieren wir die zweite ssh-Konfigurationsdatei:

Code:
sudo nano /etc/ssh/sshd_config

In dieser Datei befindet sich folgende Zeile:

Code:
ChallengeResponseAuthentication no

und dort ändern wir das "no" zu "yes":

Code:
ChallengeResponseAuthentication yes

Wir speichern die Datai via Strg+x. Dann rufen wir google-authenticator auf (OHNE sudo!):

Code:
google-authenticator

Und bestätigen jeweils immer mit ja bzw. yes. Dies erzeugt einen QR-Code in der Konsole, welcher mit dem Smartphone und der google-authenticator-App abphotographiert werden kann. Die App erzeugt nun entsprechende 2FA-Token. Wie das aussieht könnt ihr hier sehen:

https://ryanerickson.com/add-two-factor-aut/

Direkt unter dem QR-Code befindet sich der 2FA-Masterkey ("new secret key") und wiederum direkt darunter der sogenannte "verification code" (VC). Den 2FA-Masterkey braucht ihr euch nicht merken oder notieren. Wichtig ist aber der VC für die weitere Installation!

GANZ WICHTIG!!! JA NICHT AUSLOGGEN!!! DIESE VERBINDUNG IMMER OFFEN LASSEN BIS 2FA AUCH WIRKLICH FUNKTIONIERT.

Zusätzlich wurde der Ordner

Code:
/home/thorsten/.google_authenticator

erzeugt, welcher die 2FA-Konfiguration für Nutzer thorsten enthält. Wird dieser gelöscht, geht auch diese Konfiguration verloren (siehe auch weiter unten).

Nun starten wir den ssh-Dienst neu:

Code:
sudo systemctl stop ssh
sudo systemctl start ssh

Zum Aktivieren und Testen von 2FA öffnen wir eine neue Konsole und versuchen uns am Server anzumelden:

Code:
ssh thorsten@192.168.178.101

  • Ein erstes Passwort wird abgefragt: Gebt hier den VC ein. Wenn nicht der korrekte VC eingegeben wird, dann kann man Einrichtung von google-authenticator auf dem Server gleich nochmal durchexerzieren.
  • Ein zweites Passwort wird abgefragt: Dies ist nun das Nutzerpasswort von euch bzw. hier im Beispiel von thorsten.
  • Ein Verification Code wird abgefragt: Hierbei handelt es sich um das 2FA-Token, welches vom Zweitgerät alle 30 Sekunden neu generiert wird.

Wenn das geklappt hat, einfach ausloggen und nochmal das Ganze:

Code:
ssh thorsten@192.168.178.101

Bei Passwort diesmal das Nutzerpasswort eingeben, dann kommt auch gleich die Token-Abfrage.

Falls 2FA nicht klappt, dann macht die Änderungen in

Code:
/etc/pam.d/sshd

und

Code:
sudo nano /etc/ssh/sshd_config

rückgängig. In ersterer Datei reicht das Auskommentieren der neuen Zeile:

Code:
#auth required pam_google_authenticator.so

In zweiterer Datei schlicht "yes" wieder durch "no" austauschen. Zusätzlich muss der Ordner:

Code:
/home/thorsten/.google_authenticator

gelöscht werden. Last but not least den ssh-Dienst wieder neu starten:

Code:
sudo systemctl stop ssh
sudo systemctl start ssh

Es kann nun zur Fehlersuche wieder von vorne bei Einrichtung von google-authenticator auf dem Server begonnen werden. Wenn alle Stricke reissen, dann könnt ihr die Dateien bei Nutzung eines Raspis auch direkt auf der SD-Karte editieren, wenn diese in einem PC gemountet ist, anstatt das System vollständig neu aufzusetzen.

Bemerkungen zu verschlüsselten Daten

Im Folgenden gehe ich davon aus, dass dem Angreifer das Nutzerpasswort sowie der 2FA-Masterkey unbekannt ist.

Für einen erfolgreichen ssh-Login mit 2FA muss der Ordner:

Code:
/home/thorsten/.google_authenticator

entschlüsselt vorliegen. D.h. bei direktem Zugriff auf die Hardware und bei unverschlüsseltem Homeverzeichnis könnte ein Angreifer beliebige Informationen aus diesem auslesen. Ist jedoch das Homeverzeichnis verschlüsselt, dann kann das System nicht auf die 2FA-Konfiguration zugreifen. Ein Henne-Ei-Problem.

Eine ziemlich unhandliche Lösung wäre, dass der Adim des Servers immer dafür sorgt, dass das Homeverzeichnis während des laufenden Betriebs entschlüsselt vorliegt. Wie schon erwähnt, ist das Homeverzeichnis verschlüsselt, z.B. durch Nutzung von ecryptfs (https://wiki.ubuntuusers.de/ecryptfs/), so ist kein erfolgreicher Login bei aktiviertem 2FA möglich, da das System nicht an die 2FA-Konfiguration kommt! Ist 2FA beim Neustart des Servers deaktiviert so kann man sich normal per ssh auf dem Server einloggen und das Homeverzeichnis wird bei aktiviertem ecryptfs entschlüsselt. Nun aktiviert man 2FA. Sollte nun ein Angreifer Zugriff auf die Hardware des Servers bekommen, so kann er nicht die Daten im Homeverzeichnis der SD-Karte auslesen, da beim Ausschalten/Steckerziehen das entschlüsselte Homeverzeichnis mit der 2FA-Konfiguration sowie die anderen Daten im Homeverzeichnis verloren gehen (zumindest gehe ich davon aus). Zugriff ist per ssh auch unterbunden, da der Angreifer das Nutzerpasswort und die notwendigen 2FA-Tokens nicht kennt. Wird der Server jedoch abgeschaltet, so muss der Admin vor einem Neustart jedesmal dafür sorgen, dass 2FA deaktiviert ist. Und dies geht nur, wenn er dies durch manuelles Mounten und Editieren der SD-Karte am PC macht (/etc/pam.d/sshd und /etc/ssh/sshd_config).

Referenzen

https://ryanerickson.com/add-two-factor-aut/
https://wiki.archlinux.org/index.php/Google_Authenticator
5  Local / Anfänger und Hilfe / Die erste Primzahl mit 21 zusammenhängenden Stellen in e on: January 22, 2020, 07:51:38 AM
ist die:

957496696762772407663

und taucht schon hier auf:

2.718281828459045235360287471352662497757247093699959574966967627724076630353547 ...

Das ist nicht ungewöhnlich, da (pi(10^22) - pi(10^21))/(10^22 - 10^21) immer noch relativ klein ist (pi(x) ist grob gleich x/log(x)). D.h. selbst bei so großen Zahlen ist, wenn ich mich nicht verrechnet habe, jede ca. 50te Zahl eine Primzahl. Diese läßt sich logischerweise in drei Siebener-Gruppen oder sieben Dreier-Gruppen "zerlegen" ...

Warum? Deshalb:

https://cryptomonday.de/21-bitcoin-zu-verschenken-wer-loest-das-mysterioese-btc-puzzle/
https://www.blockchain.com/btc/address/1h8BNZkhsPiu6EKazP19WkGxDw3jHf9aT

Immer auch das Originalbild beachten, da sind vllt. Informationen versteckt (https://de.wikipedia.org/wiki/Steganographie). Da ist ein einziger schwarzer Pixel ausserhalb des Gesichts im rechten unteren Viertel des Bildes (man muss dazu etwas reinzoomen). Das ist bestimmte kein Zufall. Desweiteren scheint die 21 eine Rolle zu spielen (Annahme von mir).

Bye.

Gefunden via deterministischem von mir angepassten (256bit) Miller-Rabin-Test (https://de.wikipedia.org/wiki/Miller-Rabin-Test und https://rosettacode.org/wiki/Miller%E2%80%93Rabin_primality_test):

Code:
// gcc -Wall <file_name>.c -o <file_name> -lcrypto -std=c99
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#include <boost/multiprecision/cpp_int.hpp>

using namespace boost::multiprecision;

/*static char *qtoa(uint256_t n){
   static char buf[80];
   unsigned int i, j, m = 79;
   memset(buf, 0, 80);
   for (i = 256; i-- > 0;){
      int carry = !!(n & ((uint256_t)1 << i));
      for (j = 79; j-- > m + 1 || carry;){
         int d = 2*buf[j] + carry;
         carry = d > 9;
         buf[j] = carry ? d - 10 : d;
      }
      m = j;
   }
   for (i = 0; i < 78; i++){
      if (buf[i]){
         break;
      }
   }
   for (j = i; j < 79; j++){
      buf[j] += '0';
   }
   return buf + i;
}*/

// calcul a^n%mod
uint256_t power(uint256_t a, uint256_t n, uint256_t mod)
{
    uint256_t power = a;
    uint256_t result = 1;
    while (n)
    {
        if (n & 1)
            result = (result * power) % mod;

        power = (power * power) % mod;

        n >>= 1;
    }
    return result;
}

// n−1 = 2^s * d with d odd by factoring powers of 2 from n−1
bool witness(uint256_t n, uint256_t s, uint256_t d, uint256_t a)
{
    uint256_t x = power(a, d, n);
    uint256_t y;
    while (s) {
        y = (x * x) % n;
        if (y == 1 && x != 1 && x != n-1)
            return false;
        x = y;
        --s;
    }
    if (y != 1)
        return false;
    return true;
}

/*
 * if n < 1,373,653, it is enough to test a = 2 and 3;
 * if n < 9,080,191, it is enough to test a = 31 and 73;
 * if n < 4,759,123,141, it is enough to test a = 2, 7, and 61;
 * if n < 1,122,004,669,633, it is enough to test a = 2, 13, 23, and 1662803;
 * if n < 2,152,302,898,747, it is enough to test a = 2, 3, 5, 7, and 11;
 * if n < 3,474,749,660,383, it is enough to test a = 2, 3, 5, 7, 11, and 13;
 * if n < 341,550,071,728,321, it is enough to test a = 2, 3, 5, 7, 11, 13, and 17;
 * if n < 318,665,857,834,031,151,167,461, it is enough to test a = 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37.
 */

bool is_prime_mr(uint256_t n)
{
    if (((!(n & 1)) && n != 2 ) || (n < 2) || (n % 3 == 0 && n != 3))
        return false;
    if (n <= 3)
        return true;

    uint256_t d = n / 2;
    uint256_t s = 1;
    while (!(d & 1)) {
        d /= 2;
        ++s;
    }

    if (n < 1373653)
        return witness(n, s, d, 2) && witness(n, s, d, 3);
    if (n < 9080191)
        return witness(n, s, d, 31) && witness(n, s, d, 73);
    if (n < 4759123141)
        return witness(n, s, d, 2) && witness(n, s, d, 7) && witness(n, s, d, 61);
    if (n < 1122004669633)
        return witness(n, s, d, 2) && witness(n, s, d, 13) && witness(n, s, d, 23) && witness(n, s, d, 1662803);
    if (n < 2152302898747)
        return witness(n, s, d, 2) && witness(n, s, d, 3) && witness(n, s, d, 5) && witness(n, s, d, 7) && witness(n, s, d, 11);
    if (n < 3474749660383)
        return witness(n, s, d, 2) && witness(n, s, d, 3) && witness(n, s, d, 5) && witness(n, s, d, 7) && witness(n, s, d, 11) && witness(n, s, d, 13);
    if (n < 341550071728321)
        return witness(n, s, d, 2) && witness(n, s, d, 3) && witness(n, s, d, 5) && witness(n, s, d, 7) && witness(n, s, d, 11) && witness(n, s, d, 13) && witness(n, s, d, 17);

    return witness(n, s, d, 2) && witness(n, s, d, 3) && witness(n, s, d, 5) && witness(n, s, d, 7) && witness(n, s, d, 11) && witness(n, s, d, 13) && witness(n, s, d, 17) && witness(n, s, d, 19) && witness(n, s, d, 23) && witness(n, s, d, 29) && witness(n, s, d,
 31) && witness(n, s, d, 37);
}

void padstring(char hexstring[], char *buf){
   int l = strlen(hexstring);
   for (int i = 0; i < 64 - l; i++)
      buf[i] = '0';

   for (int i = 0; i < l; i++)
      buf[64 - l + i] = hexstring[i];
}

uint256_t string2int256(char hexstring[]){
   unsigned char val[32];
   for (int i = 0; i < 32; i++)
      sscanf(&hexstring[2*i], "%2hhx", &val[i]);

   uint256_t ret = 0;
   for (int i = 0; i < 32; i++){
      ret = ret << 8;
      ret = ret | val[i];
   }

   return ret;
}

int main(int argc, char *argv[]){
   char buf[128] = {0};
   padstring(argv[1], buf);
   uint256_t x = string2int256(buf);
   printf("%d\n", is_prime_mr(x));

   return 0;
}

Compilieren via (die benötigten Biblotheken vorausgesetzt):

Code:
g++ -Wall mr.c -o mr

Input sollte in Hexadezimal erfolgen:

Code:
echo "obase=16;ibase=10;957496696762772407663" | bc

und

Code:
./mr 33E7EF9CABBAF6C56F

ergibt 1.
6  Local / Presse / Telepolis: Halbherziger Bankkonto-Datenschutz unter PSD2 on: November 27, 2019, 07:03:41 PM
https://www.heise.de/tp/features/Halbherziger-Bankkonto-Datenschutz-unter-PSD2-4596818.html

Fand ich ganz interessant, wofür das Feigenblatt PSD2 so alles gut sein soll ... Shocked
7  Local / Anfänger und Hilfe / [Howto] Adressen-Monitoring on: November 17, 2019, 11:20:31 AM
Warnung: Wer Wallet oder Adressen per Electrum überwacht, deanonymisiert sich gegenüber dem Electrum-Server selbst!!!

Zum Nachrecherchieren hat mich folgender Beitrag gebracht:

https://bitcointalk.org/index.php?topic=5276680.msg55217179#msg55217179

Und folgende Aussage darin:


Quote
[...] Dazu sammeln sie  z.B. auch Daten von Electrum-Wallet anfragen für die sie selber jede Menge Server betreiben [...]

D.h., wer sich mit einem Electrum-Server verbindet und nach einer Balance fragt, ob nun mit oder ohne Privatekeys, muss die entsprechenden Adressen an den Server ausliefern.

https://medium.com/shiftcrypto/use-the-bitbox02-with-electrum-wallet-5088219b8497

Der Server weiss dann, dass sich eine bestimmte IP für bestimmte Adressen interessiert. Die IP selbst ist noch nicht mit einem Namen verknüpft, aber die Gegend, aus welcher die Anfrage kommt kann schon auf der Landkarte eingegrenzt werden. Zusätzlich ändern Standardrouter heutzutage nicht mehr regelmäßig die IP, sodass Angreifer möglicherweise versuchen könnten, diese zu hacken. Oder man kommt anderweitig and die Identität hinter der IP.

Also entweder mit TOR oder VPN oder gar nicht.




Anbei eine Anleitung für die ganz Paranoiden, wie man die eigenen Coins live trackt und bei Änderungen per SMS benachrichtigt wird. Dieser Thread ist work-in-progress. Ich bitte um Geduld, falls dieser noch unvollständig ist.

Einleitung
Voraussetzungen
Einrichtung

Einleitung

Es gibt imho fünf Methoden für diesen Zweck, denn bekanntlich führen viele Wege nach Rom, welche ihre ureigensten Vor- und Nachteile haben. Zwei wurden hier im Forum schon besprochen (https://bitcointalk.org/index.php?topic=3310218.0):

  • Monitoring des Mempools (https://bitcointalk.org/index.php?topic=3310218.msg42604663#msg42604663):
    • Vorteil: Passiv. Leicht einzurichten. Man benötigt ausser einem Computer, welcher online ist, kaum etwas.
    • Nachteil: Wenn der Server ausfällt, können Änderungen nicht registriert werden, da diese Methode Blockchain-unabhängig ist.
  • Monitoring eines Blockexplorers (https://bitcointalk.org/index.php?topic=3310218.msg36027146#msg36027146):
    • Vorteil: Man überlässt Blockchain und Mempool einem externen Dienstleister.
    • Nachteile:
      • Sehr wartungsintensiv, da Dienstleister das Outputformat jederzeit ändern kann, was Nachbesserungen notwendig macht.
      • Aktiv. Jede Abfrage der Balance ohne die Nutzung von https zeigt dem Internet, dass sich eine IP für eine bestimmte Adresse interessiert. Jede Abfrage der Balance zeigt dem Dienstleister, dass sich eine IP für eine bestimmte Adresse interessiert. Jede Abfrage der Balance via TOR zeigt dem Exitnode, dass sich jemand für eine bestimmte Adresse interessiert.
      • Gefahr, dass die eigene IP beim Dienstleister gesperrt wird, wenn man es mit der Anzahl der Abfragen übertreibt.
      • Eine Menge, möglicherweise unötiges, Rumgeskripte.
  • Monitoring via Fullnode:
    • Vorteil: Passiv. Man hat alle notwendigen Daten lokal vorliegen. Man erweitert zusätzlich das P2P-Bitcoinnetzwerk.
    • Nachteil: Nur für Experten geeignet.
  • Monitoring via Smartphone-App:
    • Vorteil: Ermöglicht jederzeit eine Benachrichtigung.
    • Nachteile: Nutzung einer Drittanbieter-App. Zusätzlich muss man ständig online sein, was im Ausland oder in Funklöchern teuer oder schwierig sein kann.

Ich möchte in diesem Thread eine weitere, fünfte Methode präsentieren, welche zwischen der ersten und dritten Methode angesiedelt ist und welche auf der Electrum-Familie basiert. Die Vorteile sind folgende:
  • Diese Methode ist passiv und gibt praktisch nichts nach aussen hin preis.
  • Die Software selbst ist durchgehend online und beobachtet den Mempool.
  • Man hat, abhänigig von den Adressen von Interesse, eine Light-Version der Blockchain (Blockheaders) lokal vorliegen. Diese wird nach Serverpausen synchronsieren sodass man immer auf dem neusten Stand ist.
  • Wichtig: Es lassen sich Watch-Only-Wallets erzeugen, d.h dass man Adressen in eine Wallet importieren kann, der Privatekey ist nicht notwendig! Man kann also beliebige Adressen beobachten.
  • Die Methode läßt sich praktisch durch copy und paste an andere Kryptowährungen anpassen (vorausgesetzt für diese existiert eine Electrum-Wallet, z.B. BCH, LTC, NMC u.a.).

Warum ich diesen Thread schreibe? Aus Spass an der Freude. Ausserdem möchte ich, dass das in schön dokumentiert ist sodass die entsprechenden Schritte für die Zukunft gesichert sind.

Voraussetzungen

Wir benötigen:
  • (etwas) Linux- und Kommandozeilenerfahrung.
  • Einen Raspberry Pi 4 mit 4 GB, da Electrum auf dem entsprechenden Raspbian out-of-the-box läuft. Ansonsten hat man nur Frickelei.
  • Ein entsprechendes Netzteil, da der Raspi 4 per USB-C versorgt wird, alte Netzteile passen nicht!
  • Eine SD-Karte und hier empfehle ich eine SanDisk Extreme 64GB U3 A2 XCI V30, die es in jedem Mediamarkt oder Saturn gibt. Diese soll relativ gut mit einem Raspberry Pi zusammenspielen (las ich irgendwo, den Link muss ich aber noch raussuchen).
  • Ein SMS-Gateway. Ich würde gerne lima-city.de empfehlen, da diese Seite einst Bitcoin akzeptierte und so eine Bezahlung für ein SMS-Kontingent relativ anonym und sicher ablief. Leider wurde diese Zahlungsmethode dieses Jahr rausgenommen. Ich weiss nicht ob es inzwischen wieder geht. Es gibt auch andere solche Dienstleister, aber dort ist meist nur Kreditkartenzahlung möglich und diese ist inherent unsicher!

Rest, coming soon.

Einrichtung

Vorbereitung SD-Karte

Ich gehe davon aus, dass es sich beim Client-Rechner, also jenem Rechner, vor dem ihr sitzt, um eine Linux-System handelt, welches ist dabei (fast) egal. Die Anleitung basiert auf Ubuntu. Als Nutzername nehme ich heinz an und dass der Ordner /home/heinz/Downloads/raspbian existiert. Mit Windows kenne ich mich leider nicht (mehr) aus. Windows-Nutzer können prinzipiell ein Ubuntu-Livesystem nutzen, müßen dieses aber auch erstmal auf einen USB-Stick bekommen.

Zu Beginn benötigen wir die entsprechende Raspbian-Version (https://www.raspberrypi.org/downloads/raspbian/). Bei jedem Besuch einer Seite, wo ihr Daten runterladet, solltet ihr kurz das Schlosssymbol in der Adressleiste und somit das Zertifikat überprüfen indem ihr draufklickt und euch die entsprechenden Informationen anzeigen lasst. Ich lade Raspbian immer direkt aus dem Ordner runter (https://downloads.raspberrypi.org/raspbian_latest), da man dort auch gleich die entsprechenden Signaturen findet.

Code:
cd /home/heinz/Downloads/raspbian
wget https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2019-09-30/2019-09-26-raspbian-buster-lite.zip
wget https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2019-09-30/2019-09-26-raspbian-buster-lite.zip.sig

Wir müssen das zip-Archive vorher auf Authentizität prüfen, dafür benutzte ich folgenden PGP-Schlüssel (bitte prüft den nochmal selbst!):

https://keyserver.ubuntu.com/pks/lookup?search=0x956F460C&fingerprint=on&op=index

Code:
gpg --keyserver keyserver.ubuntu.com --recv 956F460C
gpg --verify 2019-09-26-raspbian-buster-lite.zip.sig 2019-09-26-raspbian-buster-lite.zip

Wenn wir die Meldung ...

Code:
gpg: Signature made Mon 30 Sep 2019 02:43:50 PM CEST using RSA key ID 956F460C
gpg: Good signature from "Raspberry Pi Downloads Signing Key"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 54C3 DD61 0D9D 1B4A F82A  3775 8738 CD6B 956F 460C

... bekommen können wir relativ beruhigt mit der Installation fortfahren. Dazu legen wir nun die SD-Karte ein. Diese muss vorher nicht formatiert werden. Das Device, welches die SD-Karte repräsentiert, hat meist einen komischen Namen wie /dev/mmcblk0. Wenn ihr unsicher seid, dann installiert euch ggparted (sudo apt-get install ggparted; sudo gparted) und guckt, welches Device 64GB Speicher hat (rechts in der oberen Ecke kann man per Dropdown die Devices auswählen).

Nochmals Vorsicht: mmcblk ist ein Beispiel, überprüft das nochmal! Ansonsten überschreibt ihr möglicherweise eine andere SD-Karte, welche in eurem System steckt.

Code:
unzip 2019-09-26-raspbian-buster-lite.zip
sudo dd if=2019-09-26-raspbian-buster-lite.img of=/dev/mmcblk0

Das wars. Die SD-Karte enthält nun die aktuelle Version von Raspbian (wir sind aber noch nicht fertig).

Wir entfernen nun die SD-Karte, nachdem oberes Kommando durchgelaufen ist, und stecken sie wieder rein. Das OS mountet dann automatisch die Partitionen auf der SD-Karte (Ubuntu tut dies unter /media/heinz). Damit Raspbian per ssh erreichbar ist muss die leere Datei "ssh" erstellt werden:

Code:
sudo touch /media/heinz/rootfs/ssh

Zusätzlich sollten wir die Netzwerkkonfiguration von Raspbian anpassen:

Code:
sudo nano /media/heinz/rootfs/etc/network/interfaces

Wir füllen die Datei mit etwas Ähnlichem wie:

Code:
# interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto eth0
allow-hotplug eth0
iface eth0 inet static
address 192.168.178.101
netmask 255.255.255.0
gateway 192.168.178.1
dns-nameservers 192.168.178.1

Die oberen IP-Adressen hängen davon ab wie euer Heimnetzwerk konfiguriert ist. In oberem Beispiel ist der Raspi nun unter 192.168.178.101 zu erreichen. Die IP für den DNS-Nameserver mag bei euch eine andere sein. Nano kann man per Strg+x verlassen. Das Programm fragt nach ob die Änderungen gespeichert werden sollen.

Der SD-Karte ist nun fertig konfiguriert damit wir auf dem Raspi loslegen können. Dazu unmounten wir die SD-Karte, entfernen sie aus dem Client-Rechner, stecken sie in den Raspi, verbinden den Raspi mit einem Netzwerkkabel, welches mit dem entsprechenden Netzwerk verbunden ist sowie mit dem Netzteil sodass der Raspi booten kann.

Konfiguration des Raspi

Wir verbinden uns mit dem Raspi (Windows-Nutzer können diesen Schritt mit putty realisieren: https://www.putty.org/):

Code:
ssh pi@192.168.178.101

Das Passwort ist standardmäßig "raspberry". Natürlich müßt ihr 192.168.178.101 durch die von euch gewählte IP austauschen.

Zu Beginn werden wir aus Sicherheitsgründen einen neuen Nutzer mit beliebigen Namen erzeugen (z.B. thorsten), nur noch diesen nutzen und den pi-Nutzer blockieren:

Code:
sudo adduser thorsten

Vergebt ein Passwort und lasst den Rest leer. Zusätzlich muss der neuer Nutzer der Gruppe sudoers hinzugefügt werden, damit er entsprechende Rechte hat:

Code:
sudo adduser thorsten sudo

Jetzt blockieren wir noch den pi-Nutzer:

Code:
sudo usermod -L -e 1 pi

Von nun an kann der pi-Nutzer sich nicht mehr im System anmelden. Wieder freischalten läßt sich der pi-Nutzer durch:

Code:
sudo usermod -U -e 99999 pi

Wichtig: Diese Konfiguration verhindert, bei ausreichend gutem Passwort, dass der Raspi im Betrieb nicht kompromitiert werden kann, vorausgesetzt, dass niemand Zugriff auf die Hardware hat. Kommt jemand an den Raspi, dann kann er den Stecker ziehen, die SD-Karte entfernen und an einem bliebigen Rechner mit SD-Kartenleser die auf der Karte unverschlüsselten Dateien analysieren. Und das sind praktisch alle Dateien. Man kann den Raspi auch dagegen härten, d.h. dass dann alle wichtigen Dateien dort verschlüsselt sind und nur im laufenden Betrieb entschlüsselt vorliegen. Das ist aber nicht das Thema hier. Anleitungen dazu gebe ich ein andermal (ecryptfs, ufw, knockd, google-authenticator).

Nun aus dem Raspi ausloggen:

Code:
exit

Und als neuer Nutzer wieder einloggen:

Code:
ssh thorsten@192.168.178.101

Nun machen wir erstmal ein systemweites Update:

Code:
sudo apt-get update
sudo apt-get dist-upgrade

Wer will kann den Raspi über ...

Code:
sudo raspi-config

... weitergehend konfigurieren. Es bietet sich an "Advanced Options" -> "Expand Filesystem" auszuwählen sowie unter "Localisation Options" -> "Change Timezone" die entsprechende Örtlichkeit einzustellen.

Auch sollten wir den Raspi selbst umbenennen, denn wenn zwei oder mehr Rechner mit dem selben Hostnamen im lokalen Netz hängen, dann können diese sich gegenseitig blockieren (geht alternativ auch über raspi-config):

Code:
sudo nano /etc/hosts

Dort nun wo "raspberry" steht einen anderen Namen eintragen und nano mit Strg+x verlassen. Das gleiche machen wir hier:

Code:
sudo nano /etc/hostnames

Danach rebooten:

Code:
sudo shutdown -r now

Der Reboot geht fix, nach ein paar Sekunden können wir uns wieder auf dem Raspi einloggen:

Code:
ssh thorsten@192.168.178.101

Jetzt passen wir noch den Swap an, damit wir noch ordentlich Platz haben, falls die 4 GB RAM des Raspis mal nicht ausreichen sollten:

Code:
sudo nano /etc/dphys-swapfile

Dort setzen wir den Auslagerungsspeicher auf 16 GB, wir hams ja:

Code:
CONF_SWAPSIZE=16384

Wir beenden nano via Strg+x und aktivieren den Swap durch:

Code:
sudo dphys-swapfile setup
sudo dphys-swapfile swapon

Am besten rebooten wir nochmal, wobei ich mir nicht sicher bin, ob das notwendig ist aber schaden kann es nicht:

Code:
sudo shutdown -r now

Einrichtung von Electrum

Electrum gibt es hier: https://electrum.org/. Dort prüfen wir erst das Schlosssymbol in der Adressleiste. Dann, unter Downloads, kann man die für verschiedene OS bereitgestellten Varianten runterladen. Sehr schön auf der Seite: Unten werden auch die notwendigen Kommandos für die Installation angegeben.

Wie dort angegeben installieren wir zu Beginn qt5, damit dann später, falls notwendig, auch die GUI funktioniert:

Code:
sudo apt-get install python3-pyqt5

Jetzt erzeugen wir den Download-Ordner, holen uns Electrum, die entsprechenden Signatur sowie den Publickey von Thomas Voegtlin:

Code:
mkdir /home/thorsten/Downloads
cd /home/thorsten/Downloads
wget https://download.electrum.org/3.3.8/Electrum-3.3.8.tar.gz
wget https://download.electrum.org/3.3.8/Electrum-3.3.8.tar.gz.asc
wget https://raw.githubusercontent.com/spesmilo/electrum/master/pubkeys/ThomasV.asc

Wir importieren den Publickey:

Code:
gpg --import ThomasV.asc

Alternativ kann man den Publickey auch von einem Keyserver importieren:

Code:
gpg --keyserver keyserver.ubuntu.com --recv 6694d8de7be8ee5631bed9502bd5824b7f9470e6

Achtung: Überprüft diesen Schritt bewusst doppelt da ihr euch hier fremde Software auf euer System holt!

Wir verifizieren das Archiv:

Code:
gpg --verify Electrum-3.3.8.tar.gz.asc Electrum-3.3.8.tar.gz

Und können nach ...

Code:
gpg: Signature made Thu Jul 11 16:26:15 2019 CEST
gpg:                using RSA key 6694D8DE7BE8EE5631BED9502BD5824B7F9470E6
gpg: Good signature from "Thomas Voegtlin (https://electrum.org) <thomasv@electrum.org>" [unknown]
gpg:                 aka "Thomas Voegtlin <thomasv1@gmx.de>" [unknown]
gpg:                 aka "ThomasV <thomasv1@gmx.de>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 6694 D8DE 7BE8 EE56 31BE  D950 2BD5 824B 7F94 70E6

... relativ beruhigt fortfahren. Jetzt entpacken wir noch Electrum und sind damit mit der Installation schon am Ende angekommen.

Code:
tar -xzvf Electrum-3.3.8.tar.gz

Die Hilfe zum Electrum-Skipt, welches wir benutzen werden, rufen wir wie folgt auf:

Code:
/home/thorsten/Downloads/Electrum-3.3.8/run_electrum -h

Ein bisschen Linux, Bash und Electrum

Wir loggen uns aus und wieder ein, diesmal mit dem "-X" Flag, um per Electrum-GUI eine Watch-Only-Wallet zu erzeugen:

Code:
exit
ssh thorsten@192.168.178.101 -X

Wir starten Electrum:

Code:
/home/thorsten/Downloads/Electrum-3.3.8/run_electrum

Und klicken uns durch den Wallet-Wizard: "Auto connect" -> "Next" -> "default_wallet" -> "Next" -> "Import Bitcoin addresses or private keys" -> "Next". In das weiße Editierfeld kopieren wir die Adressen von Interesse, jeweils mit Zeilenumbruch, z.B. drei von diesen seltsamen 8000 BTC-Adressen von denen es seit 2018 so viele gibt, ...

Code:
1MYv4C4hZ7hC5sbHrPkzvmNoozQgnHKeAU
182p5CrqfDxvonznRyi5AUBwsCkDX8eYMe
1LyTftu54VMYCv5pq3S4pMzPRMnsYKTESw

... und drücken "Next". Die Passwortinformationen können wir leer lassen, handelt es sich ja sowieso nur um eine Watch-Only-Wallet: "Next". Beim "Electrum - Enable update check" könnt ihr wählen, was euch besser gefällt. Dann heisst es ein bisschen warten, bis sich die Wallet synchronisiert hat. Nach erfolgreicher Synchronisierung steht vor jeder Transaktion ein grünes Häckchen. Falls der Text "not verified" sich nicht ändert, dann hilft es, die Wallet zu schliessen und neu zu starten. Der Text, welcher auf der Kommandozeile vom Programm ausgegeben wird, kann ignoriert werden.

Wir erzeugen den Ordner "watch.btc", erzeugen dort die Datei "addresses" und kopieren in diese die Adressen von Interesse:

Code:
cd /home/thorsten
mkdir watch.btc
cd watch.btc
nano addresses

Die Datei "addresses" schliessen wir per Strg+x. Dann erzeugen wir das Bash-Skript "watch.sh":

Code:
nano watch.sh

Und füllen dieses mit folgendem Code:

Code:
#!/bin/bash
while true; do
   echo -n "" > output;
   while read address; do
      /home/thorsten/Downloads/Electrum-3.3.8/run_electrum getaddressbalance "$address" >> output;
   done < addresses;

   now=$(date '+%Y-%m-%d %H:%M:%S');
   diff=$(cmp balance output);
   if [[ "$diff" != "" ]]; then
      echo -e "$now\tchange detected";
      epoch=$(date --date="$now" +"%s");
      mv balance balance."$epoch";
      mv output balance;

      ##################
      # do other stuff #
      ##################
   else
      echo -e "$now\tok";
   fi

   sleep 60;
done;

(Alternativ kann man auch den RPC-Befehl getbalance nutzen:

Code:
/home/thorsten/Downloads/Electrum-3.3.8/run_electrum getbalance

Dann bekommt man die Summe der Beträge über alle in der Wallet enthaltenen Adressen. Dafür muss aber die Wallet zu Beginn geladen werden (siehe Cronjob weiter unten).)

Wir speichern das Skript indem wir nano per Strg+x verlassen. Zusätzlich erzeugen wir die Datei "balance":

Code:
echo "blubb" > balance

Zu guter Letzt erzeugt wir einen Cronjob, welcher das Watch-Skript bei jedem Neustart des Raspi startet:

Code:
crontab -e

Beim ersten Aufruf von oberem Kommando muss man einen Editor wählen. Wir wählen wieder nano und fügen dann unten folgende Zeile an:

Code:
@reboot /home/thorsten/Downloads/Electrum-3.3.8/run_electrum daemon start; sleep 180; cd /home/thorsten/watch.btc/; ./watch.sh >> log

(Alternativ: Will man den RPC-Befehl getbalance nutzen muss der Cronjob wie folgt aussehen:

Code:
@reboot /home/thorsten/Downloads/Electrum-3.3.8/run_electrum daemon start; sleep 60; /home/thorsten/Downloads/Electrum-3.3.8/run_electrum daemon load_wallet; sleep 120; cd /home/thorsten/watch.btc/; ./watch.sh >> log
)

Dieses Kommando startet kurz nach einem Reboot den Electrum-Dienst, welcher im Hintergrund läuft. Dann wird drei Minuten gewartet, damit sich Electrum synchronisieren kann. Daraufhin startet unser Watch-Skript über unsere Adressen in der Datei "addresses" zu loopen. Für jede Adresse fragt dieses Skript die aktuelle Balance ab. Das Ergebnis wird in die Datei "output" geschrieben. Wenn alle Adressen abgearbeitet sind wird "output" mit "balance" verglichen. Sind beide Dateien gleich, dann wird in die Datei "log" ein "ok" mit Datum geschrieben. Sind die Dateien unterschiedlich, so wird die alte "balance" Datei mit Unixzeit (https://de.wikipedia.org/wiki/Unixzeit) im Namen gesichert und die aktuelle "output" Datei wird zur "balance" Datei. Der Vorgang wiederholt sich alle 60s.

Nun haben wir einen Server, welcher unsere Adressen von Interesse überwacht. Natürlich ist die in diesem Abschnitt beschriebene Methode um die einzelnen Balances zu prüfen nur einen Methode von vielen. Eine andere Methode ist, dass man den Output von Electrum direkt innerhalb von python analysiert, da dieser ja sowieso im JSON-Format ausgegeben wird. Das ist also reine Geschmackssache.

Anbindung an SMS-Gateway

Wenn ihr einen Account bei einem SMS-Gateway habt (hier beispielhaft für https://www.lima-city.de, da sehr zu empfehlen) und euch ein SMS-Kontingent gekauft habt (mehrere hundert SMS bekommt man für unter 20€), dann fügt unter den auskommentierten Text im watch-Skript Folgendes ein (eurer Kreativität ist da aber keine Grenze gesetzt):

Code:
     ##################
      # do other stuff #
      ##################

      info=$(wget -qO- "https://api.lima-city.de/sms?user_id=<user_id>&apikey=<api_key>&text=<text>&number=<tel_nummer>");

z.B.:

Code:
     ##################
      # do other stuff #
      ##################

      info=$(wget -qO- "https://api.lima-city.de/sms?user_id=123456&apikey=viet2ieteepeuRae0eengeiphaif1diegai4uSh9&text=hallo&number=004917712345678");

Die <user_id> und den <api_key> bekommt ihr bei lima-city (siehe auch https://www.lima-city.de/hilfe/sms-kontingente). Die <tel_nummer> ist die eures Mobiltelefons. Der <text> kann von euch frei gewählt werden. Wichtig: Stellt sicher, dass https genutzt wird und NICHT http!!! Ansonsten wird eure id und euer API-Key im Plaintext im Internet verschickt.
8  Economy / Speculation / Bitcoin price and Benford's law on: October 02, 2019, 06:16:25 AM
The first digit of numbers often follow Benford's law. Manipulation of those numbers by humans can be detected via corresponding statistic tests since humans cannot produce numbers following the needed distribution(s) (except they use a computer and know, that the original data follows Benford's law):

https://en.wikipedia.org/wiki/Benford%27s_law
https://en.wikipedia.org/wiki/Benford%27s_law#Price_digit_analysis

Now something to think about and to discuss (but maybe I used the following tools wrongly):

Some R:
https://www.rdocumentation.org/packages/benford.analysis/versions/0.1.5

Code:
library(anytime); # für Zeitumrechnung
library(benford.analysis); # für Benford

temp <- tempfile();
download.file("https://api.bitcoincharts.com/v1/csv/bitstampUSD.csv.gz", temp);
table <- read.csv(gzfile(temp));
unlink(temp);

rm(temp);
gc();

# Benennung der Spalten
colnames(table) <- c("EPOCH", "PRICE", "VOLUME");

# Anfügen einer neuen Spalten mit den Daten (Datums), da ansonsten Epochs
table <- cbind(table, "DATE"=anydate(table[,1], "CEST"));

x <- benford(table$PRICE);
plot(x);

y <- getSuspects(x, table);
#hist(as.Date(y$DATE), breaks=1000);
hist(as.Date(unique(y$DATE)), breaks=314)

z <- y[grepl("2019", y$DATE),];
unique(z$DATE);

Some results:

General distribution of bitstamp's price digits:


General statistics of data:
Code:
Benford object:
 
Data: table$PRICE
Number of observations used = 34361833
Number of obs. for second order = 1636552
First digits analysed = 2

Mantissa:

   Statistic Value
        Mean  0.58
         Var  0.10
 Ex.Kurtosis -1.19
    Skewness -0.46


The 5 largest deviations:

  digits absolute.diff
1     10      820554.5
2     20      604793.2
3     19      575172.8
4     11      574876.8
5     18      561510.5

Stats:

Pearson's Chi-squared test

data:  table$PRICE
X-squared = 11178000, df = 89, p-value < 2.2e-16


Mantissa Arc Test

data:  table$PRICE
L2 = 0.090839, df = 2, p-value < 2.2e-16

Mean Absolute Deviation (MAD): 0.005221502
MAD Conformity - Nigrini (2012): Nonconformity
Distortion Factor: 21.44937

Time points where price digits do not follow Benford's law:


The corresponding time points for 2019 (note the date, when this started and when it ended!):
Code:
[1] "2019-06-21" "2019-06-22" "2019-06-23" "2019-06-24" "2019-06-27"
 [6] "2019-06-28" "2019-06-30" "2019-07-01" "2019-07-02" "2019-07-03"
[11] "2019-07-05" "2019-07-06" "2019-07-11" "2019-07-13" "2019-07-14"
[16] "2019-07-15" "2019-07-16" "2019-07-18" "2019-07-19" "2019-07-20"
[21] "2019-07-21" "2019-07-22" "2019-07-23" "2019-07-25" "2019-07-27"
[26] "2019-07-31" "2019-08-01" "2019-08-02" "2019-08-03" "2019-08-04"
[31] "2019-08-05" "2019-08-13" "2019-08-14" "2019-08-15" "2019-08-16"
[36] "2019-08-17" "2019-08-18" "2019-08-19" "2019-08-20" "2019-08-21"
[41] "2019-08-22" "2019-08-23" "2019-08-24" "2019-08-25" "2019-08-26"
[46] "2019-08-27" "2019-08-28" "2019-09-02" "2019-09-03" "2019-09-04"
[51] "2019-09-05" "2019-09-06" "2019-09-07" "2019-09-08" "2019-09-09"
[56] "2019-09-10" "2019-09-11" "2019-09-12" "2019-09-13" "2019-09-14"
[61] "2019-09-15" "2019-09-16" "2019-09-17" "2019-09-18" "2019-09-19"
[66] "2019-09-20" "2019-09-21" "2019-09-22" "2019-09-23"

References: https://bitcointalk.org/index.php?topic=26136.msg52592024#msg52592024
9  Economy / Speculation / A hidden markov model for sentiment prediction and price forecasting on: May 12, 2019, 07:22:55 PM
The following text is a translation of one of my comments: https://bitcointalk.org/index.php?topic=4586924.msg41380372#msg41380372. The translation was done quickly but will improve with time.

Prerequisites
Introduction
Hidden Markov Models for sentiment analysis
Trading by means of a Hidden Markov Model
Price forecasting with a Markov Chain
Discussion
Outlook
References

Prerequisites

Installation of R

R is a free programming language, which specializes on statistical computing (https://en.wikipedia.org/wiki/R_(programming_language)):

https://www.r-project.org/

This is the only software package needed so that the following code snippets should work by copy and paste. Additionally, it makes sense to install Rstudio:

https://www.rstudio.com/

Rstudio is a graphical user interface and programming environment for R and simplifies programming in R as well as the managment of data.

Installation of necessary R-packages

The following code, executed in R, installs packages, which are necessary or might be useful at later timepoints.

Code:
install.packages(c("zoo", "anytime", "data.table", "depmixS4"));

Packages are loaded in R as follows:

Code:
library(zoo);
library(anytime);
library(data.table);
library(depmixS4);

Introduction

Example with ideal and manipulated die

The following example is chosen in such a way, that it is analogous to chart analysis.

Suppose you take part in the Mensch Ärgere Dich Nicht World Championship (DNGAWC in the following, which stands for the english translation: Do Not Get Angry World Championchip). For this game you need a die. If you throw a six, you may throw the die again. Furthermore, the player with the six has the choice to come out or throw again normally. Thus, throwing a six is ​​an advantage. For an ideal die, the probability is exactly 1/6, as well as for the other numbers. You could try to help luck via using a manipulated die, which looks as similar as possible to the official die of the world championship. Hence, it would be good, if the organizers of the DNGAWC would be able to detect whether an official die was used or not. Cheating players would then be disqualified from the championship.

At the beginning we consider the ideal die and compare it with the manipulated die. The manipulated die should increase the probability of throwing a six. We assume in this example, that the probability for a six with the manipulated die is 2/7 and for the other numbers 1/7 each. We now throw both dice very often and note down the sequence of the thrown numbers:

Code:
library(zoo);
library(depmixS4);

# ideal die
x_ideal <- floor(runif(1000000)*6)+1; # throw very often
x_manip <- floor(runif(1000000)*7)+1; x_manip[x_manip==7] <- 6; # throw very often

To get a feeling for the distribution of the numbers, we combine 500 throws via a moving window on both sequences respectively (also compare other window sizes). We note the mean value for each window and plot the corresponding mean value distribution for both sequences:

Code:
y_ideal <- rollapply(x_ideal, width=500, FUN=mean);  # combine 500 throws
h_ideal <- hist(y_ideal, 50, plot=FALSE); # create histogram
h_ideal$density <- h_ideal$counts/sum(h_ideal$counts);  # normalize density

y_manip <- rollapply(x_manip, width=500, FUN=mean);  # combine 500 throws
h_manip <- hist(y_manip, 50, plot=FALSE); # create histogram
h_manip$density <- h_manip$counts/sum(h_manip$counts);  # normalize density

plot(h_ideal, col=rgb(0,0,1,1/4), xlim=c(3.3, 4.1), freq=FALSE, main="Mean of 500 throws with\nideal (left) and manipulated die (right)", xlab="mean", ylab="frequency");  # first histogram
plot(h_manip, col=rgb(1,0,0,1/4), xlim=c(3.3, 4.1), freq=FALSE, add=TRUE); # second histogram

z <- seq(3.3, 4.1, 0.001); # points on x-axis
lines(z, dnorm(z, mean(y_ideal), sqrt(var(y_ideal)))/100, col="blue");  # plot normal distribution with parameters from simulation
lines(z, dnorm(z, mean(y_manip), sqrt(var(y_manip)))/100, col="red");  # plot normal distribution with parameters from simulation
abline(v=mean(y_ideal), col="blue"); # mark mean
abline(v=mean(y_manip), col="red"); # mark mean

The result is shown in the plot below:


Obviously, the two distributions are gaussian. If a sequence was created with the ideal die, then the mean of 500 throws should come from the left distribution. If a sequence was generated with the manipulated die, then the mean comes from the right distribution. If a sequence was created via both dice, then the mean should come either from one or the other distribution. Whether a sequence was created with one or two different dice, i.e., whether the dice were exchanged during the game, can now be detected with a Hidden Markov Model (HMM). However, an important requirement for this example is, that the number of consecutive throws with each die is large (e.g., 10000) compared to the window size (500).

The HMM modelling one die consists of one node and an one edge. In the case of the ideal die, the node corresponds to the upper blue normal distribution. The node generates numbers such that the distribution of the mean from 500 die throws follows the blue normal distribution. Since there is only one edge with the probability P = 1.0, the new state of the HMM after each roll MUST be the old one:


If the ideal die is exchanged by a manipulated die during the game, the corresponding HMM consists of at least two nodes. A node that generates the distribution of the ideal die and a node that generates the distribution of the manipulated die:


The edges with the probabilities P(blue to blue), P(blue to red), P(red to red) and P(red to blue) depend on how often the dice were exchanged during the game. Here, the sequence of numbers should be long enough that more than two exchanges (state changes) took place! The more the better.

An HMM whose parameters are known is also called Markov chain. A Markov chain, interpreted as a model for a given (stochastic) process, mimics that process mathematically and thus represents something like a simulation of the process. In our example, this would be the simulation of the numbers thrown by a fair player or the numbers thrown by a cheater during the DNGAWC.

Thus, an HMM is an automaton, i.e., a graph with several nodes (states) and edges (state changes). One of the nodes is special since it determines the state the automaton currently is in. The edges are labeled with probabilities so that the sum of the outgoing edges sums up to the probability of P = 1.0. The automaton then jumps in discrete steps from node to node along the edges, according to the probabilities indicated at the edges. Since the sum of the probabilities at the outgoing edges is equal to 1.0, the automaton changes its state in each step, though the new state can be the same as the old one. If the HMM is in state A and with the next jump, the state changes to B (with A! = B), then you have a (real) state change.

In the case of an HMM, the parameters of the model, i.e. the probabilities at the edges of the automaton, are not known in the beginning and must be deduced from given data. This is also called fitting the model to the data and the result is simply called the fitted HMM. Having found the optimal parameters, one can now compute the most probable path over the nodes over time through the graph. The sequence of nodes that the automaton passes through is called hidden states (hidden/unknown states). In our example, the data ONLY consist of the thrown die numbers. The hidden states correspond to the use of the dice, i.e. when an ideal die and when a manipulated die was used in the sequence of thrown numbers.

We now generate a simulated sequence of thrown die numbers, which satisfies our requirements (many thrown die numbers in a row by the same die and many dice exchanges), and try to detect the dice exchanges in the resulting number sequence by means of a fitted HMM:

Code:
set.seed(1); # set random set for reproducibility

# generate sequence with ideal and manipulated die
a <- floor(runif(10000)*6)+1;
b <- floor(runif(50000)*7)+1; b[b==7] <- 6;
c <- floor(runif(20000)*6)+1;
d <- floor(runif(10000)*7)+1; d[d==7] <- 6;
e <- floor(runif(30000)*6)+1;
f <- floor(runif(20000)*7)+1; e[e==7] <- 6;
g <- floor(runif(40000)*6)+1;

sequence <- c(a,b,c,d,e,f,g);
mseq <- as.data.frame(t(t(rollapply(sequence, width=500, FUN=mean))));
colnames(mseq) <- c("MEAN");

The generation of the HMM, the fit of the model to the data and the extraction of relevant data is a three liner in R:

Code:
# generate and fit Hidden Markov Modell
hmm <- depmix(MEAN ~ 1, family = gaussian(), nstates = 2, data=mseq);
hmmfit <- fit(hmm, verbose = FALSE);
post_probs <- posterior(hmmfit);


For the generation of a meaningful plot, we need more code:

Code:
dev.new(width=19, height=3.5); # create plot
matplot(post_probs[,-1], type="l", col=c("blue", "red"), lty = c(1,1), xaxt="n"); # plot posterior probabilities

axis(1, at = 10000*(0:18), labels = 10000*(0:18)); # normalize x-axis
legend("left", legend = c("ideal", "gezinkt"), col = c("blue", "red"), lty = c(1,1), lwd = 1 , xpd = T ); # legend
title("Würfel-HMM mit zwei Zuständen"); # titel

# generate sequence of HMM states
for (i in 1:nrow(post_probs)){rect(i-1, 0, i, -0.1, col=c("blue", "red")[post_probs[i,1]], border=NA)}

# posterior probabilities
summary(hmmfit);
hmmfit@transition;

The result should look as follows:


On the x-axis, the sequence of states is shown as colored horizontal band. The curves in the plot represent the (a posteriori) probability for the corresponding die at the given time point. Note that the HMM does not reproduce the states perfectly (see also other window sizes). This is due to statistical fluctuations, which means that the blue distribution may look like the red by coincidence (and vice versa). Because of the window, of course, there are less than 180,000 states (179501). Due to numerical inaccuracies, the real transition probabilities can only be accessed using the command "hmmfit@transition". The command "summary(hmmfit)" is not sufficient, because it apparently rounds the probabilities! The corresponding HMM is then given by the following graph:


Discussion of resulting variables

Todo: Discussion of resulting variables

Comparison and selection of models

If the organizers suspect a player to cheat during the DNGAWC, then they must also be able to quantify their suspicion. They must be able to quantify how likely it is that the suspect uses a manipulated rather than an ideal die. In the simplest case, one compares two different models of the suspect: The null hypothesis (H0) is, that the suspect uses an ideal cube; The alternative hypothesis (H1) is, that the suspect uses an additional manipulated die. H0 is discarded if H1 is much more likely. Of course, one can still generate additional models of increasing complexity (H2, ..., Hn), e.g. to model the assumption that the suspect has used multiple different manipulated dice with different parameters. One of those models must be selected in such a way that the probability is minimized to exclude an innocent player from the world championship.

Just as graphs can be varied in their parameters, i.e. in the number of nodes, edges, and thus in their topology (structure), different HMMs can be generated (H0, ..., Hn) and can be fitted to the same data, assuming, that they model reality, respectively. Each fitted HMM will have a certain likelihood. The likelihood here is the "probability" of the HMM given the data and it can be interpreted as a kind of probability. There are also other concepts that are analogous to the likelihood. The best known are the Akaike Information Criterion (AIC) and the Bayesian Information Criterion (BIC). Given an unfitted HMM, there is virtually always only one fit of the (hidden) states (or a behavior of the HMM automaton over time) to the data, which is the most likely. However, the other fitted HMMs might be similarly likely, even though the absolut value of their likelihood is worse compared to the best fit. In such a case you have to decide which model to choose for further analysis to prevent overfitting.

The naive approach consists of simply choosing the HMM that has the highest likelihood. However, this approach has the problem that a model with more parameters usually ALWAYS has the higher likelihood. At the same time, however, the model loses its general meaning (overfitting) or becomes more difficult to interpret. This means for the set of HMMs to be examined, that the corresponding model parameters, i.e. the number of states, are chosen to be as "reasonable" as possible. However, even in this scenario, the choice of the HMM with highest likelihood can be poor, since simpler models with fewer parameters, that is, HMMs with fewer states, may have "similar" high likelihoods. In this situation, one should choose the HMM with fewest states from the set of HMMs with "similar" high likelihood (Ockham's Razor). How to do that in detail, you can find here: https://stats.stackexchange.com/questions/81427/aic-guidelines-in-model-selection.

Even with new data, the likelihood of one and the same HMM can change, creating a completely different fit. The Expectation-Maximization algorithm (EM algorithm) guarantees to find local maxima but it does not necessarily find the global maximum (sequence of the calculation of an HMM fit: EM algorithm and then Viterbi algorithm). If one fits a model with different random seeds, one might end in different local maxima. In this situation, the random seed can be interpreted as a new parameter and this case can be treated as described in the last paragraph. (Source: https://bitcointalk.org/index.php?topic=26136.msg45063876#msg45063876)

Limits of a model

I do not want to talk much about the limitations of a model. However, I link a documentation where imho everything important is said (The Midas Formula). Although the video does not explicitly refer to the limits of models, but the basic message should be clear in the end. It is important to fully watch the video:

https://vimeo.com/28554862

Hidden Markov Models for sentiment analysis

A price-return Hidden Markov Model

The return of a specific time interval t, e.g. of a specific week, is the difference between closing price and opening price divided by the closing price:

Code:
return[t] <- (x$CLOSE_PRICE[t] - x$OPEN_PRICE[t])/x$CLOSE_PRICE[t]   # in R "<-" corresponds to ":=" or "=" in other programming languages

If the closing price is greater than the opening price, the return is positive, if the opening price is greater than the closing price, the return is negative, and if the closing price is equal to the opening price, the return is zero. The return of an asset that continuously varies by a certain average (e.g., like tethers around US $ 1), with no medium to long term swings down or up, can be modeled with a (normal) distribution of mean zero. The return of an asset where, on the other hand, there are additional market situations in which the price also falls or rises in the long term (e.g. bear and bull market in Bitcoin), it makes sense to model these three market situations with at least three different distributions: the distribution of a bear market has a negative mean, the distribution of a bull market has a positive mean and the distribution of a sideways movement has a mean of zero. Those three distributions are equivalent to three different dice at the DNGAWC: a manipulated die where the probability of throwing a six is ​​less than 1/6, an ideal die and a manipulated die where the probability of throwing a six is greater than 1/6.

At https://github.com/trantute/sentiment-hmm, two exemplary HMMs are implemented. The first HMM models four states: bearish, sideways, bullish and bubble (see the plot below). The second HMM models five states: dead, bearish, sideways, bullish and bubble.


The states of the HMM over time are shown as colored horizontal band on the x-axis in the plot above. The posterior probabilities as well as the logarithmized price (normalized to 1.0) and the logarithmized MA203 (normalized to 1.0) are shown as curves in the plot. The sentiment is indicated by color, as described above as well as defined in the legend on the left side in the plot. The corresponding graph is given below:


Robustness analysis

The question arises how trustworthy the sentiment prediction for the current week actually is. Simulations with historical data have shown that the predictions are relatively stable if the market is not volatile in the medium to long term (sideways phase) or in a medium to long-term downward or upward trend (not shown). However, simulations of historical data as well as real data have also shown that an extreme change in price, which has a significant impact on the weekly return, can subsequently change the sentiment prediction. Below, the fits of seven consecutive weeks are shown:


The states of the HMM over time are shown as colored horizontal band on the x-axis in the plot above. As can be seen on the right side in the plot above, a state is unstable, in particular, if the HMM has just changed its state recently, or if different states for the current week have a similar likelihood. The posterior probabilities for the different states (the curves in the plot) can provide information about this. If all states have posterior probabilities not equal to 0.0 - as in the upper plot on the right - then the current state is more unstable than if one state has the posterior probability close to 1.0 and the others close to 0.0.

Other variants

The return as proxy for the sentiment is only one possibility for an HMM. Other variables can be used too, insofar they show a correlation with the sentiment. E.g. the comments per time interval at bitcointalk.org could be used as proxy. Corresponding code can also be found at https://github.com/trantute/sentiment-hmm.

Trading by means of a Hidden Markov Model

If the sentiment is known or if one is able to estimate the sentiment sufficiently accurate, then this knowledge can be used to act accordingly. The idea is to go long at the beginning of an uptrend and short at the beginning of a downtrend. For the plots shown above, this means for example: bearish (red) => short; sideways (black) => long; bullish (green) => long; and bubble (violett) => long. In addition, the plot contains the logarithmized Bitcoin price (US $, Bitstamp, normalized to 1.0) for the corresponding time points (blue) and the MA203 (Moving average for 203 days = 29 weeks, orange) which corresponds approximately to the MA200 but is easier to calculate.

Of course, trading only makes sense, if the sentiment changes from black, green or purple to red or vice versa. For this you have to keep an eye on two weeks each, i.e. suppose today is a Monday, yesterday was Sunday and the HMM has predicted a change of state relative to the previous Sunday. Now you exchange your asset according to the rules mentioned. Namely to the opening price of the current week, so the current Monday. (Source: https://bitcointalk.org/index.php?topic=26136.msg43234811#msg43234811)

Todo: Code

Todo: Test with historic data

Exchange conditions can be additionally optimized. The example from above is quite naive: 0:100, 100:0, 100:0 and 100:0. This are just four parameters. One could search the space of exchange ratios using historic data for finding the ratios maximizing the yield. E.g. steps of 0.1 result in only 10000 possibilities and one choses the ratios which maximizes the yield (in dollar or BTC). In particular, assuming that one can ONLY go long or short, i.e. all in or all out, the computational effort is manageable, since the exchange ratios would then be binary variables. With n = 4 states there would be only 2^4 = 16 possibilities. Such a method may also be useful in finding the best parameter set of the HMM, but with the risk that the model loses generality by overfitting on historical data. (Source: https://bitcointalk.org/index.php?topic=26136.msg43256510#msg43256510)

Price forecasting with a Markov Chain

Todo: Explanation, how to do this. See also https://github.com/trantute/sentiment-hmm for a 4-state-HMM. Also simulations with historic data are needed.

Discussion

It is important to note, that the characteristics of the underlying probability distributions might continuously change over time (phase transition)! For instance, the return probability distribution of a bearish sentiment might be different in 2014 and 2018. As a result, over long time periods, one has to experiment, whether additional states, which model the same sentiment at different points in time but with different probability distributions, improve the power of the model.

Outlook

Todo: Ideas come in here. E.g., price/return forecast via a fitted HMM/Markov chain.

References

https://www.wikipedia.org/
https://api.bitcoincharts.com/v1/csv/
http://web.stanford.edu/class/stats366/exs/HMM1.html
https://www.quantstart.com/articles/hidden-markov-models-for-regime-detection-using-r
https://www.fool.com/knowledge-center/how-to-calculate-return-on-indices-in-a-stock-mark.aspx
https://stats.stackexchange.com/questions/81427/aic-guidelines-in-model-selection
https://github.com/trantute/sentiment-hmm
10  Economy / Trading Discussion / Please remove on: May 05, 2019, 12:42:19 PM
Please remove
11  Local / Off-Topic (Deutsch) / Alles Heuchler on: April 06, 2019, 05:29:35 PM
Nicht, dass dies jetzt irgendwas Neues wäre. Einem wachen Beobachter bleibt sowas nicht verborgen. Aber hier nochmal als ausgearbeiteter Artikel:

https://www.heise.de/tp/features/Flygskam-Scham-und-Schande-fuer-das-Fliegen-mit-dem-Flugzeug-4354163.html

Ob TP nun Qualtitätsjournalismus ist, darüber mag man streiten. Wenigstens werden bestimmte Themen aus anderen Blickrichtungen betrachtet. Und selbst der SPIEGEL blies schon ins gleiche Horn.

Man kann gar nicht soviel Thunfischberge fressen wie man kotzen möchte.
12  Local / Anfänger und Hilfe / (Juristische) Verträge in der Blockchain on: January 24, 2019, 06:46:46 AM
Die Blockchain wird immer als grosses Notarbuch beworben. Aber wie wird darin ein Vertrag abgelegt? Und wäre solch ein Vertrag vor Gericht rechtskräftig?

Ich habe darüber nachgedacht und nicht weiter recherchiert, gehe aber davon aus, dass sich jemand schon einen Kopf darüber gemacht hat ...

Mein Vorgehen wäre: Einen Text entwerfen analog zu https://bitcointalk.org/index.php?topic=920631.0. Z.B.:

Quote
trantute2 verpflichtet sich, dass er heute zur Arbeit geht. trantute2 wird bis 9:30 des 2019-01-24 eine Transaktion auf jene Bitcoin-Adresse veranlassen, welche den sha256-Hash dieses Textes als Privatekey hat. Diese Transaktion muss ihren Ausgangspunkt von einer Adresse haben, welche mit dem Bitcoin.de-Konto von trantute2 assoziiiert ist.

Die Adresse, auf welche ich eine Transaktion senden müßte, wäre dann

Quote
1N7StfEwsUV85BSjb2UhrdAHtVm51uhp8d

wenn mich nicht alles täuscht.

Meine Identität wäre über die Bitcoin.de-Transaktion mit diesem Vertrag verknüpft. Die Coins wären nicht verloren, da der Privatekey durch den Text generiert wird. Und keiner weiss von dem Vertrag solange dessen Wortlaut unbekannt ist. Ein Vertragspartner muss natürlich vom Wortlaut Kenntnis haben, damit er diesen auch vor Gericht verwenden kann.

Macht das Sinn? Und hätte das, unabhängig vom leicht verständlichen Wortlaut des Textes, prinzipiell Bestand vor Gericht?
13  Economy / Trading Discussion / Some R-code, which might be helpful for trading on: December 20, 2018, 09:03:26 AM
Some R-code, I am developing for around half a year:

https://bitcointalk.org/index.php?topic=4586924.0

and

https://github.com/trantute

The bitcointalk-link is in german and I am too lazy to translate it in the moment. However, if there is real interest for a translation, I would invest the time. The code should speak for itself.

Tell me what you think or even improve it.

Have fun.
14  Local / Anfänger und Hilfe / bc<andere Zeichen>-Adresse in Bitcointransaktion on: November 23, 2018, 07:31:31 AM
Folgende Adresse fiel mir gerade:

bc1q6rxc7zajptl5r3mgp7rk94p5fffpets94u7504

in folgender Transaktion auf:

https://www.blockchain.com/btc/tx/a806e656836b8c08ccccb16a9067a79ae9ba92f70f4f5ed433a674626eb294f3

Man kann diese nicht weiterverfolgen und auch andere Explorer kapitulieren davor.

Kann mir kurz jemand einen Hinweis geben was es damit auf sich hat. Scheint ja valide zu sein.
15  Local / Projektentwicklung / Flaschenpfand, Blockchain und (Bit)coin on: October 01, 2018, 02:24:36 PM
Ich las gerade den Spiegel-Artikel:

Cent um Cent

DER SPIEGEL, Nr. 38 / 15. 9. 2018, Seite 52

Dort geht es um Betrug am Pfandflaschenautomaten. D.h. z.B. das mehrfache Abrechnen der gleichen Flasche u.ä. um mehr Geld ausbezahlt zu bekommen als man Pfandflaschen abgegeben hat. Es gibt da eine Pfandflaschenabrechnungsbehörde in Berlin, dann noch bis zu 6000 Abfüller sowie die Behörden, welche den Betrug verfolgen. Also ein Loch ohne Boden bzw. sinnlose deutsche Arbeitsbeschaffungsmaßnahme und somit ein Fall für das Bullshitbingowort "Blockchain"!

Ich stelle mir das über Multisig so vor: Es gibt EINEN Masterprivatekey, den die Pfandflaschenbehörde besitzt, sowie für jede Flasche bzw. das dazugehörige Etikett einen eigenen Privatekey (Etikettkey). Der Masterkey ist nur der Pfandflaschenbeörde bekannt. Der Etikettkey wird vom Abfüller erzeugt und ist nur dem Abfüller bekannt. Mit Hilfe der beiden dazugehörigen Publickeys wird eine Adresse mit dem entsprechenden Pfandwert beladen (pay to script hash).

D.h. die Pfandflaschenbehörde kommt nicht direkt an den Pfand, aber auch nicht der Abfüller der Flasche oder der Käufer der Flasche. Der Etikettkey ist unter einer Schutzschicht versteckt und MUSS aufgerubbelt werden. Ansonsten könnte sich ja jeder diesen im Laden notieren. Dies wiederum bedeutet, dass man nur volle Pfandflaschen kauft, deren Etikettkey unangetastet sind. Die anderen läßt man stehen, sind diese doch manipuliert. Das ist dann das Problem des Ladens, welcher dafür sorgen muss, dass die Etikettkeys nicht mutwillig aufgerubbelt werden. Ich weiss jetzt noch nicht ob das mit dem Aufrubbeln wirklich notwendig ist, aber belassen wir es als zusätzliches Sicherheitsfeature mal dabei.

Ist die Flasche aufgerubbelt, dann kann sie im Pfandflaschenautomaten abgeben werden. Zusätzlich wird bei Abgabe von Flaschen noch eine Zieladresse mit angegeben, wohin das Pfand überwiesen werden soll. Der Pfandflaschenautomat kommt von einem beliebigen Dritthersteller, aber möglichst nicht von der Pfandflaschenbehörde. Dieser liest den Privatekey der Flasche ein und signiert eine Transaktion entsprechend der Gesamtsumme des abgegebenen Pfands auf die Zieladresse (noch zu lösen ist, dass der Pfandflaschenautomat die Zieladresse nicht ändert, irgendwas mit Smartphone). Diese Transaktion wird an die Pfandflaschenbehörde gesendet, welche ihrerseits die Transaktion signiert. Ist alles korrekt abgelaufen, dann wird die entsprechende Menge Coins and die Zieladresse gesendet. Der Pfandautomat misst natürlich noch Gewicht und Form des abgegebenen Objekts damit auch eine Flasche abgegen wurde.

Natürlich könnte man sogar noch jede Flasche mit einer eindeutigen ID versehen, sodass die Transaktion nur durchgeht, wenn die ID der Flasche korrekt ist und nicht einfach ein Etikett abgegeben wurde, d.h. dass das Etikett mit der Flasche übereinstimmt. Z.B. über dreier Multisig: Auf der Flasche ist offen ein Privatekey eingeritzt (Flaschenkey) und mit den entsprechenden drei Publickeys wird die daraus resultierende Adresse beladen. Man benötigt dann alle drei Objekte: Masterkey, Etikettkey und Flaschenkey.

Hierbei gibt es natürlich noch das Problem der Coinvolalität: 15 Cent sind dann mal 10 Cent und dann mal 20 Cent wert ... . Ausserdem sollte der Coin eine hohe Blockfinderate haben, z.B. Litecoin u.ä..

Vielleicht mit Kanonen auf Spatzen geschossen ... who knows.
16  Local / Presse / [2018-08-31] scinexx.de: Bitcoins aus dem Bergwerk (ein ganzes Dossier!) on: August 31, 2018, 06:32:31 AM
http://www.scinexx.de/dossier-881-1.html

Das ist schon bemerkenswert, wenn die deutschsprachige Seite für Neuigkeiten aus den Naturwissenschaften ein ganzes Dossier dem guten alten Bitcoin widmet. ^^
17  Local / Anfänger und Hilfe / bitcointalk-Beitrag mit Link auf Absatz on: August 08, 2018, 08:55:18 AM
Hallo,

kann mir jemand bei dem Problem helfen einen Link auf einen Absatz in einem Beitrag zu setzen?

Also z.B.:



Einführung[ref:eins]
Hauptteil[ref:zwei]
Ausführung[ref:drei]

[eins]Einführung

bla fasel

[zwei]Hauptteil

bla fasel blubb

[drei]Ausführung

bla laber



Einführung, Hauptteil und Ausführung sollen dann klickbar sein und auf den entsprechenden Absatz verlinken
18  Local / Trading und Spekulation / Methoden und Algorithmen zur fortgeschrittenen Kursanalyse on: July 02, 2018, 06:56:23 PM
Hallo,

da dies angefragt wurde mache ich mal diesen Thread auf. Der Sinn und Zweck des Threads ist es, Methoden zu diskutieren, welche über Technische Analyse (https://de.wikipedia.org/wiki/Technische_Analyse), Sentimentanalyse (https://de.wikipedia.org/wiki/Sentimentanalyse) und Fundamentalanalyse (https://de.wikipedia.org/wiki/Fundamentalanalyse), wie man sie aus "Der Aktuelle Kursverlauf" her kennt, hinaus geht. Es soll darum gehen, die Methoden zu diskutieren, auszuprobieren und zu erweitern. D.h. ihr könnt Code posten, welcher möglichst funktionieren sollte oder auf Projekte, falls umfangreicher, auf entsprechenden Repositories verweisen. Auch sind konstruktive Vorschläge zu Methoden gern gesehen (Link etc.pp.).

Die Methoden und der Code sind derart aufbereitet, dass dieser prinzipiell per Copy und Paste lauffähig sein sollte. Ihr müsst nur die entsprechenden und angegebenen Softwarepakete installieren und zum Laufen bekommen. Das sollte als Startpunkt für eure eigene Analysen reichen. Momentan plane ich nicht darüber hinauszugehen.

Mir selbst sind in den letzten Monaten folgende Methoden in den Sinn gekommen:


Der letzte Punkt läuft zwar auch unter Machine Learning, ist aber doch etwas umfangreicher und komplexer. Deshalb als eigener Punkt. Ihr könnt gerne weitere Punkte vorschlagen.
19  Local / Projektentwicklung / Erster Standard für Post-Quantum-Signaturen on: June 20, 2018, 06:17:48 AM
https://www.heise.de/security/meldung/Erster-Standard-fuer-Post-Quantum-Signaturen-4085522.html

https://tools.ietf.org/html/rfc8391

Der Quantencomputer stellt also prinzipiell keine Gefahr mehr dar. Natürlich müsste dies oder etwas Ähnliches noch in Bitcoin und Co eingebaut werden. Und dann muss man wohl erstmal alle Coins von A nach B verschieben. Rechtzeitig.
20  Local / Anfänger und Hilfe / Trezor Hardwarewallet und die Seeds/Accounts on: June 18, 2018, 02:54:19 PM
Meine kurze und hoffentlich leicht zu beantwortende Frage (falls schon gefragt, bitte ich darum mich dahin zu verweisen).

Wie ich die Privatekeyverwaltung verstehe (BIP soundso, kann ja jemand anderes rauskramen):

  • Masterseed: wird erzeugt aus Wortliste
  • Unterseeds (private): erzeugen deterministisch Privatekeys
  • Unterseeds (public): erzeugen deterministisch Publickeys und Adressen ohne den Privatekey zu kennen (DAS muss man sich mal auf der Zunge zergehen lassen  Shocked )
  • Verschiedene Accounts
  • Verschiedene Coins

Alles unter dem Masterseed wird aus dem Masterseed erzeugt. Nun die eigentliche Frage:

Hat jeder Account einen eigenen Unterseed? Und bekommt jeder Coin der vom Trezor unterstützt wird einen eigenen neuen Account mit Unterseed? Wäre nur logisch.

Ich frage, da man beim Importieren der Publickeyseed in Electrum angeben muss, welche Keyderivation man nutzen möchte: m/44’/0’/0’, m/49’/0’/0’ oder noch was anderes. Jetzt gibt die zweite Null z.B. die Account# an (https://blog.trezor.io/using-trezor-with-electrum-v3-a0b9bcffe26e). Was nun, wenn man eine Bitcoin- und Litecoin Wallet erzeugt, beide jeweils mit z.B. m/44’/0’/0’. Bekommen diese zwei Wallets dann den gleichen Satz Privatekeys oder geht der Typ des Coins in die Unterseed mit ein. Wie gesagt, das wäre nur logisch.

Privatekey ist ja bei vielen Coins gleich Privatekey und ähnlich wie bei BTC und BCH kann man mit dem gleichen Privatekey verschieden Coins versorgen. Die Adresse sähe nur anders aus. Jedoch, bei der ersten Transaktion aus einer Adresse heraus würde der Publickey veröffentlicht und dieser wäre dann der gleiche wie beim anderen Coin.
Pages: [1] 2 »
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!