-
@ e3ba5e1a:5e433365
2025-02-05 17:47:16
I got into a [friendly discussion](https://x.com/snoyberg/status/1887007888117252142) on X regarding health insurance. The specific question was how to deal with health insurance companies (presumably unfairly) denying claims? My answer, as usual: get government out of it!
The US healthcare system is essentially the worst of both worlds:
* Unlike full single payer, individuals incur high costs
* Unlike a true free market, regulation causes increases in costs and decreases competition among insurers
I'm firmly on the side of moving towards the free market. (And I say that as someone living under a single payer system now.) Here's what I would do:
* Get rid of tax incentives that make health insurance tied to your employer, giving individuals back proper freedom of choice.
* Reduce regulations significantly.
* In the short term, some people will still get rejected claims and other obnoxious behavior from insurance companies. We address that in two ways:
1. Due to reduced regulations, new insurance companies will be able to enter the market offering more reliable coverage and better rates, and people will flock to them because they have the freedom to make their own choices.
2. Sue the asses off of companies that reject claims unfairly. And ideally, as one of the few legitimate roles of government in all this, institute new laws that limit the ability of fine print to allow insurers to escape their responsibilities. (I'm hesitant that the latter will happen due to the incestuous relationship between Congress/regulators and insurers, but I can hope.)
Will this magically fix everything overnight like politicians normally promise? No. But it will allow the market to return to a healthy state. And I don't think it will take long (order of magnitude: 5-10 years) for it to come together, but that's just speculation.
And since there's a high correlation between those who believe government can fix problems by taking more control and demanding that only credentialed experts weigh in on a topic (both points I strongly disagree with BTW): I'm a trained actuary and worked in the insurance industry, and have directly seen how government regulation reduces competition, raises prices, and harms consumers.
And my final point: I don't think any prior art would be a good comparison for deregulation in the US, it's such a different market than any other country in the world for so many reasons that lessons wouldn't really translate. Nonetheless, I asked Grok for some empirical data on this, and at best the results of deregulation could be called "mixed," but likely more accurately "uncertain, confused, and subject to whatever interpretation anyone wants to apply."
https://x.com/i/grok/share/Zc8yOdrN8lS275hXJ92uwq98M
-
@ 91bea5cd:1df4451c
2025-02-04 17:24:50
### Definição de ULID:
Timestamp 48 bits, Aleatoriedade 80 bits
Sendo Timestamp 48 bits inteiro, tempo UNIX em milissegundos, Não ficará sem espaço até o ano 10889 d.C.
e Aleatoriedade 80 bits, Fonte criptograficamente segura de aleatoriedade, se possível.
#### Gerar ULID
```sql
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE FUNCTION generate_ulid()
RETURNS TEXT
AS $$
DECLARE
-- Crockford's Base32
encoding BYTEA = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
timestamp BYTEA = E'\\000\\000\\000\\000\\000\\000';
output TEXT = '';
unix_time BIGINT;
ulid BYTEA;
BEGIN
-- 6 timestamp bytes
unix_time = (EXTRACT(EPOCH FROM CLOCK_TIMESTAMP()) * 1000)::BIGINT;
timestamp = SET_BYTE(timestamp, 0, (unix_time >> 40)::BIT(8)::INTEGER);
timestamp = SET_BYTE(timestamp, 1, (unix_time >> 32)::BIT(8)::INTEGER);
timestamp = SET_BYTE(timestamp, 2, (unix_time >> 24)::BIT(8)::INTEGER);
timestamp = SET_BYTE(timestamp, 3, (unix_time >> 16)::BIT(8)::INTEGER);
timestamp = SET_BYTE(timestamp, 4, (unix_time >> 8)::BIT(8)::INTEGER);
timestamp = SET_BYTE(timestamp, 5, unix_time::BIT(8)::INTEGER);
-- 10 entropy bytes
ulid = timestamp || gen_random_bytes(10);
-- Encode the timestamp
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 0) & 224) >> 5));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 0) & 31)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 1) & 248) >> 3));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 1) & 7) << 2) | ((GET_BYTE(ulid, 2) & 192) >> 6)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 2) & 62) >> 1));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 2) & 1) << 4) | ((GET_BYTE(ulid, 3) & 240) >> 4)));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 3) & 15) << 1) | ((GET_BYTE(ulid, 4) & 128) >> 7)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 4) & 124) >> 2));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 4) & 3) << 3) | ((GET_BYTE(ulid, 5) & 224) >> 5)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 5) & 31)));
-- Encode the entropy
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 6) & 248) >> 3));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 6) & 7) << 2) | ((GET_BYTE(ulid, 7) & 192) >> 6)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 7) & 62) >> 1));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 7) & 1) << 4) | ((GET_BYTE(ulid, 8) & 240) >> 4)));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 8) & 15) << 1) | ((GET_BYTE(ulid, 9) & 128) >> 7)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 9) & 124) >> 2));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 9) & 3) << 3) | ((GET_BYTE(ulid, 10) & 224) >> 5)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 10) & 31)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 11) & 248) >> 3));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 11) & 7) << 2) | ((GET_BYTE(ulid, 12) & 192) >> 6)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 12) & 62) >> 1));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 12) & 1) << 4) | ((GET_BYTE(ulid, 13) & 240) >> 4)));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 13) & 15) << 1) | ((GET_BYTE(ulid, 14) & 128) >> 7)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 14) & 124) >> 2));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 14) & 3) << 3) | ((GET_BYTE(ulid, 15) & 224) >> 5)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 15) & 31)));
RETURN output;
END
$$
LANGUAGE plpgsql
VOLATILE;
```
#### ULID TO UUID
```sql
CREATE OR REPLACE FUNCTION parse_ulid(ulid text) RETURNS bytea AS $$
DECLARE
-- 16byte
bytes bytea = E'\\x00000000 00000000 00000000 00000000';
v char[];
-- Allow for O(1) lookup of index values
dec integer[] = ARRAY[
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 255, 255, 255,
255, 255, 255, 255, 10, 11, 12, 13, 14, 15,
16, 17, 1, 18, 19, 1, 20, 21, 0, 22,
23, 24, 25, 26, 255, 27, 28, 29, 30, 31,
255, 255, 255, 255, 255, 255, 10, 11, 12, 13,
14, 15, 16, 17, 1, 18, 19, 1, 20, 21,
0, 22, 23, 24, 25, 26, 255, 27, 28, 29,
30, 31
];
BEGIN
IF NOT ulid ~* '^[0-7][0-9ABCDEFGHJKMNPQRSTVWXYZ]{25}$' THEN
RAISE EXCEPTION 'Invalid ULID: %', ulid;
END IF;
v = regexp_split_to_array(ulid, '');
-- 6 bytes timestamp (48 bits)
bytes = SET_BYTE(bytes, 0, (dec[ASCII(v[1])] << 5) | dec[ASCII(v[2])]);
bytes = SET_BYTE(bytes, 1, (dec[ASCII(v[3])] << 3) | (dec[ASCII(v[4])] >> 2));
bytes = SET_BYTE(bytes, 2, (dec[ASCII(v[4])] << 6) | (dec[ASCII(v[5])] << 1) | (dec[ASCII(v[6])] >> 4));
bytes = SET_BYTE(bytes, 3, (dec[ASCII(v[6])] << 4) | (dec[ASCII(v[7])] >> 1));
bytes = SET_BYTE(bytes, 4, (dec[ASCII(v[7])] << 7) | (dec[ASCII(v[8])] << 2) | (dec[ASCII(v[9])] >> 3));
bytes = SET_BYTE(bytes, 5, (dec[ASCII(v[9])] << 5) | dec[ASCII(v[10])]);
-- 10 bytes of entropy (80 bits);
bytes = SET_BYTE(bytes, 6, (dec[ASCII(v[11])] << 3) | (dec[ASCII(v[12])] >> 2));
bytes = SET_BYTE(bytes, 7, (dec[ASCII(v[12])] << 6) | (dec[ASCII(v[13])] << 1) | (dec[ASCII(v[14])] >> 4));
bytes = SET_BYTE(bytes, 8, (dec[ASCII(v[14])] << 4) | (dec[ASCII(v[15])] >> 1));
bytes = SET_BYTE(bytes, 9, (dec[ASCII(v[15])] << 7) | (dec[ASCII(v[16])] << 2) | (dec[ASCII(v[17])] >> 3));
bytes = SET_BYTE(bytes, 10, (dec[ASCII(v[17])] << 5) | dec[ASCII(v[18])]);
bytes = SET_BYTE(bytes, 11, (dec[ASCII(v[19])] << 3) | (dec[ASCII(v[20])] >> 2));
bytes = SET_BYTE(bytes, 12, (dec[ASCII(v[20])] << 6) | (dec[ASCII(v[21])] << 1) | (dec[ASCII(v[22])] >> 4));
bytes = SET_BYTE(bytes, 13, (dec[ASCII(v[22])] << 4) | (dec[ASCII(v[23])] >> 1));
bytes = SET_BYTE(bytes, 14, (dec[ASCII(v[23])] << 7) | (dec[ASCII(v[24])] << 2) | (dec[ASCII(v[25])] >> 3));
bytes = SET_BYTE(bytes, 15, (dec[ASCII(v[25])] << 5) | dec[ASCII(v[26])]);
RETURN bytes;
END
$$
LANGUAGE plpgsql
IMMUTABLE;
CREATE OR REPLACE FUNCTION ulid_to_uuid(ulid text) RETURNS uuid AS $$
BEGIN
RETURN encode(parse_ulid(ulid), 'hex')::uuid;
END
$$
LANGUAGE plpgsql
IMMUTABLE;
```
#### UUID to ULID
```sql
CREATE OR REPLACE FUNCTION uuid_to_ulid(id uuid) RETURNS text AS $$
DECLARE
encoding bytea = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
output text = '';
uuid_bytes bytea = uuid_send(id);
BEGIN
-- Encode the timestamp
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 0) & 224) >> 5));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 0) & 31)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 1) & 248) >> 3));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 1) & 7) << 2) | ((GET_BYTE(uuid_bytes, 2) & 192) >> 6)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 2) & 62) >> 1));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 2) & 1) << 4) | ((GET_BYTE(uuid_bytes, 3) & 240) >> 4)));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 3) & 15) << 1) | ((GET_BYTE(uuid_bytes, 4) & 128) >> 7)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 4) & 124) >> 2));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 4) & 3) << 3) | ((GET_BYTE(uuid_bytes, 5) & 224) >> 5)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 5) & 31)));
-- Encode the entropy
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 6) & 248) >> 3));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 6) & 7) << 2) | ((GET_BYTE(uuid_bytes, 7) & 192) >> 6)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 7) & 62) >> 1));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 7) & 1) << 4) | ((GET_BYTE(uuid_bytes, 8) & 240) >> 4)));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 8) & 15) << 1) | ((GET_BYTE(uuid_bytes, 9) & 128) >> 7)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 9) & 124) >> 2));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 9) & 3) << 3) | ((GET_BYTE(uuid_bytes, 10) & 224) >> 5)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 10) & 31)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 11) & 248) >> 3));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 11) & 7) << 2) | ((GET_BYTE(uuid_bytes, 12) & 192) >> 6)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 12) & 62) >> 1));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 12) & 1) << 4) | ((GET_BYTE(uuid_bytes, 13) & 240) >> 4)));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 13) & 15) << 1) | ((GET_BYTE(uuid_bytes, 14) & 128) >> 7)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 14) & 124) >> 2));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 14) & 3) << 3) | ((GET_BYTE(uuid_bytes, 15) & 224) >> 5)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 15) & 31)));
RETURN output;
END
$$
LANGUAGE plpgsql
IMMUTABLE;
```
#### Gera 11 Digitos aleatórios: YBKXG0CKTH4
```sql
-- Cria a extensão pgcrypto para gerar uuid
CREATE EXTENSION IF NOT EXISTS pgcrypto;
-- Cria a função para gerar ULID
CREATE OR REPLACE FUNCTION gen_lrandom()
RETURNS TEXT AS $$
DECLARE
ts_millis BIGINT;
ts_chars TEXT;
random_bytes BYTEA;
random_chars TEXT;
base32_chars TEXT := '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
i INT;
BEGIN
-- Pega o timestamp em milissegundos
ts_millis := FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000)::BIGINT;
-- Converte o timestamp para base32
ts_chars := '';
FOR i IN REVERSE 0..11 LOOP
ts_chars := ts_chars || substr(base32_chars, ((ts_millis >> (5 * i)) & 31) + 1, 1);
END LOOP;
-- Gera 10 bytes aleatórios e converte para base32
random_bytes := gen_random_bytes(10);
random_chars := '';
FOR i IN 0..9 LOOP
random_chars := random_chars || substr(base32_chars, ((get_byte(random_bytes, i) >> 3) & 31) + 1, 1);
IF i < 9 THEN
random_chars := random_chars || substr(base32_chars, (((get_byte(random_bytes, i) & 7) << 2) | (get_byte(random_bytes, i + 1) >> 6)) & 31 + 1, 1);
ELSE
random_chars := random_chars || substr(base32_chars, ((get_byte(random_bytes, i) & 7) << 2) + 1, 1);
END IF;
END LOOP;
-- Concatena o timestamp e os caracteres aleatórios
RETURN ts_chars || random_chars;
END;
$$ LANGUAGE plpgsql;
```
#### Exemplo de USO
```sql
-- Criação da extensão caso não exista
CREATE EXTENSION
IF
NOT EXISTS pgcrypto;
-- Criação da tabela pessoas
CREATE TABLE pessoas ( ID UUID DEFAULT gen_random_uuid ( ) PRIMARY KEY, nome TEXT NOT NULL );
-- Busca Pessoa na tabela
SELECT
*
FROM
"pessoas"
WHERE
uuid_to_ulid ( ID ) = '252FAC9F3V8EF80SSDK8PXW02F';
```
### Fontes
- https://github.com/scoville/pgsql-ulid
- https://github.com/geckoboard/pgulid
-
@ 91bea5cd:1df4451c
2025-02-04 17:15:57
### Definição de ULID:
Timestamp 48 bits, Aleatoriedade 80 bits
Sendo Timestamp 48 bits inteiro, tempo UNIX em milissegundos, Não ficará sem espaço até o ano 10889 d.C.
e Aleatoriedade 80 bits, Fonte criptograficamente segura de aleatoriedade, se possível.
#### Gerar ULID
```sql
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE FUNCTION generate_ulid()
RETURNS TEXT
AS $$
DECLARE
-- Crockford's Base32
encoding BYTEA = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
timestamp BYTEA = E'\\000\\000\\000\\000\\000\\000';
output TEXT = '';
unix_time BIGINT;
ulid BYTEA;
BEGIN
-- 6 timestamp bytes
unix_time = (EXTRACT(EPOCH FROM CLOCK_TIMESTAMP()) * 1000)::BIGINT;
timestamp = SET_BYTE(timestamp, 0, (unix_time >> 40)::BIT(8)::INTEGER);
timestamp = SET_BYTE(timestamp, 1, (unix_time >> 32)::BIT(8)::INTEGER);
timestamp = SET_BYTE(timestamp, 2, (unix_time >> 24)::BIT(8)::INTEGER);
timestamp = SET_BYTE(timestamp, 3, (unix_time >> 16)::BIT(8)::INTEGER);
timestamp = SET_BYTE(timestamp, 4, (unix_time >> 8)::BIT(8)::INTEGER);
timestamp = SET_BYTE(timestamp, 5, unix_time::BIT(8)::INTEGER);
-- 10 entropy bytes
ulid = timestamp || gen_random_bytes(10);
-- Encode the timestamp
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 0) & 224) >> 5));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 0) & 31)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 1) & 248) >> 3));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 1) & 7) << 2) | ((GET_BYTE(ulid, 2) & 192) >> 6)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 2) & 62) >> 1));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 2) & 1) << 4) | ((GET_BYTE(ulid, 3) & 240) >> 4)));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 3) & 15) << 1) | ((GET_BYTE(ulid, 4) & 128) >> 7)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 4) & 124) >> 2));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 4) & 3) << 3) | ((GET_BYTE(ulid, 5) & 224) >> 5)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 5) & 31)));
-- Encode the entropy
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 6) & 248) >> 3));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 6) & 7) << 2) | ((GET_BYTE(ulid, 7) & 192) >> 6)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 7) & 62) >> 1));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 7) & 1) << 4) | ((GET_BYTE(ulid, 8) & 240) >> 4)));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 8) & 15) << 1) | ((GET_BYTE(ulid, 9) & 128) >> 7)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 9) & 124) >> 2));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 9) & 3) << 3) | ((GET_BYTE(ulid, 10) & 224) >> 5)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 10) & 31)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 11) & 248) >> 3));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 11) & 7) << 2) | ((GET_BYTE(ulid, 12) & 192) >> 6)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 12) & 62) >> 1));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 12) & 1) << 4) | ((GET_BYTE(ulid, 13) & 240) >> 4)));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 13) & 15) << 1) | ((GET_BYTE(ulid, 14) & 128) >> 7)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 14) & 124) >> 2));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(ulid, 14) & 3) << 3) | ((GET_BYTE(ulid, 15) & 224) >> 5)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(ulid, 15) & 31)));
RETURN output;
END
$$
LANGUAGE plpgsql
VOLATILE;
```
#### ULID TO UUID
```sql
CREATE OR REPLACE FUNCTION parse_ulid(ulid text) RETURNS bytea AS $$
DECLARE
-- 16byte
bytes bytea = E'\\x00000000 00000000 00000000 00000000';
v char[];
-- Allow for O(1) lookup of index values
dec integer[] = ARRAY[
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 255, 255, 255,
255, 255, 255, 255, 10, 11, 12, 13, 14, 15,
16, 17, 1, 18, 19, 1, 20, 21, 0, 22,
23, 24, 25, 26, 255, 27, 28, 29, 30, 31,
255, 255, 255, 255, 255, 255, 10, 11, 12, 13,
14, 15, 16, 17, 1, 18, 19, 1, 20, 21,
0, 22, 23, 24, 25, 26, 255, 27, 28, 29,
30, 31
];
BEGIN
IF NOT ulid ~* '^[0-7][0-9ABCDEFGHJKMNPQRSTVWXYZ]{25}$' THEN
RAISE EXCEPTION 'Invalid ULID: %', ulid;
END IF;
v = regexp_split_to_array(ulid, '');
-- 6 bytes timestamp (48 bits)
bytes = SET_BYTE(bytes, 0, (dec[ASCII(v[1])] << 5) | dec[ASCII(v[2])]);
bytes = SET_BYTE(bytes, 1, (dec[ASCII(v[3])] << 3) | (dec[ASCII(v[4])] >> 2));
bytes = SET_BYTE(bytes, 2, (dec[ASCII(v[4])] << 6) | (dec[ASCII(v[5])] << 1) | (dec[ASCII(v[6])] >> 4));
bytes = SET_BYTE(bytes, 3, (dec[ASCII(v[6])] << 4) | (dec[ASCII(v[7])] >> 1));
bytes = SET_BYTE(bytes, 4, (dec[ASCII(v[7])] << 7) | (dec[ASCII(v[8])] << 2) | (dec[ASCII(v[9])] >> 3));
bytes = SET_BYTE(bytes, 5, (dec[ASCII(v[9])] << 5) | dec[ASCII(v[10])]);
-- 10 bytes of entropy (80 bits);
bytes = SET_BYTE(bytes, 6, (dec[ASCII(v[11])] << 3) | (dec[ASCII(v[12])] >> 2));
bytes = SET_BYTE(bytes, 7, (dec[ASCII(v[12])] << 6) | (dec[ASCII(v[13])] << 1) | (dec[ASCII(v[14])] >> 4));
bytes = SET_BYTE(bytes, 8, (dec[ASCII(v[14])] << 4) | (dec[ASCII(v[15])] >> 1));
bytes = SET_BYTE(bytes, 9, (dec[ASCII(v[15])] << 7) | (dec[ASCII(v[16])] << 2) | (dec[ASCII(v[17])] >> 3));
bytes = SET_BYTE(bytes, 10, (dec[ASCII(v[17])] << 5) | dec[ASCII(v[18])]);
bytes = SET_BYTE(bytes, 11, (dec[ASCII(v[19])] << 3) | (dec[ASCII(v[20])] >> 2));
bytes = SET_BYTE(bytes, 12, (dec[ASCII(v[20])] << 6) | (dec[ASCII(v[21])] << 1) | (dec[ASCII(v[22])] >> 4));
bytes = SET_BYTE(bytes, 13, (dec[ASCII(v[22])] << 4) | (dec[ASCII(v[23])] >> 1));
bytes = SET_BYTE(bytes, 14, (dec[ASCII(v[23])] << 7) | (dec[ASCII(v[24])] << 2) | (dec[ASCII(v[25])] >> 3));
bytes = SET_BYTE(bytes, 15, (dec[ASCII(v[25])] << 5) | dec[ASCII(v[26])]);
RETURN bytes;
END
$$
LANGUAGE plpgsql
IMMUTABLE;
CREATE OR REPLACE FUNCTION ulid_to_uuid(ulid text) RETURNS uuid AS $$
BEGIN
RETURN encode(parse_ulid(ulid), 'hex')::uuid;
END
$$
LANGUAGE plpgsql
IMMUTABLE;
```
#### UUID to ULID
```sql
CREATE OR REPLACE FUNCTION uuid_to_ulid(id uuid) RETURNS text AS $$
DECLARE
encoding bytea = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
output text = '';
uuid_bytes bytea = uuid_send(id);
BEGIN
-- Encode the timestamp
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 0) & 224) >> 5));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 0) & 31)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 1) & 248) >> 3));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 1) & 7) << 2) | ((GET_BYTE(uuid_bytes, 2) & 192) >> 6)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 2) & 62) >> 1));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 2) & 1) << 4) | ((GET_BYTE(uuid_bytes, 3) & 240) >> 4)));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 3) & 15) << 1) | ((GET_BYTE(uuid_bytes, 4) & 128) >> 7)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 4) & 124) >> 2));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 4) & 3) << 3) | ((GET_BYTE(uuid_bytes, 5) & 224) >> 5)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 5) & 31)));
-- Encode the entropy
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 6) & 248) >> 3));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 6) & 7) << 2) | ((GET_BYTE(uuid_bytes, 7) & 192) >> 6)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 7) & 62) >> 1));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 7) & 1) << 4) | ((GET_BYTE(uuid_bytes, 8) & 240) >> 4)));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 8) & 15) << 1) | ((GET_BYTE(uuid_bytes, 9) & 128) >> 7)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 9) & 124) >> 2));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 9) & 3) << 3) | ((GET_BYTE(uuid_bytes, 10) & 224) >> 5)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 10) & 31)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 11) & 248) >> 3));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 11) & 7) << 2) | ((GET_BYTE(uuid_bytes, 12) & 192) >> 6)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 12) & 62) >> 1));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 12) & 1) << 4) | ((GET_BYTE(uuid_bytes, 13) & 240) >> 4)));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 13) & 15) << 1) | ((GET_BYTE(uuid_bytes, 14) & 128) >> 7)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 14) & 124) >> 2));
output = output || CHR(GET_BYTE(encoding, ((GET_BYTE(uuid_bytes, 14) & 3) << 3) | ((GET_BYTE(uuid_bytes, 15) & 224) >> 5)));
output = output || CHR(GET_BYTE(encoding, (GET_BYTE(uuid_bytes, 15) & 31)));
RETURN output;
END
$$
LANGUAGE plpgsql
IMMUTABLE;
```
#### Gera 11 Digitos aleatórios: YBKXG0CKTH4
```sql
-- Cria a extensão pgcrypto para gerar uuid
CREATE EXTENSION IF NOT EXISTS pgcrypto;
-- Cria a função para gerar ULID
CREATE OR REPLACE FUNCTION gen_lrandom()
RETURNS TEXT AS $$
DECLARE
ts_millis BIGINT;
ts_chars TEXT;
random_bytes BYTEA;
random_chars TEXT;
base32_chars TEXT := '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
i INT;
BEGIN
-- Pega o timestamp em milissegundos
ts_millis := FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000)::BIGINT;
-- Converte o timestamp para base32
ts_chars := '';
FOR i IN REVERSE 0..11 LOOP
ts_chars := ts_chars || substr(base32_chars, ((ts_millis >> (5 * i)) & 31) + 1, 1);
END LOOP;
-- Gera 10 bytes aleatórios e converte para base32
random_bytes := gen_random_bytes(10);
random_chars := '';
FOR i IN 0..9 LOOP
random_chars := random_chars || substr(base32_chars, ((get_byte(random_bytes, i) >> 3) & 31) + 1, 1);
IF i < 9 THEN
random_chars := random_chars || substr(base32_chars, (((get_byte(random_bytes, i) & 7) << 2) | (get_byte(random_bytes, i + 1) >> 6)) & 31 + 1, 1);
ELSE
random_chars := random_chars || substr(base32_chars, ((get_byte(random_bytes, i) & 7) << 2) + 1, 1);
END IF;
END LOOP;
-- Concatena o timestamp e os caracteres aleatórios
RETURN ts_chars || random_chars;
END;
$$ LANGUAGE plpgsql;
```
#### Exemplo de USO
```sql
-- Criação da extensão caso não exista
CREATE EXTENSION
IF
NOT EXISTS pgcrypto;
-- Criação da tabela pessoas
CREATE TABLE pessoas ( ID UUID DEFAULT gen_random_uuid ( ) PRIMARY KEY, nome TEXT NOT NULL );
-- Busca Pessoa na tabela
SELECT
*
FROM
"pessoas"
WHERE
uuid_to_ulid ( ID ) = '252FAC9F3V8EF80SSDK8PXW02F';
```
### Fontes
- https://github.com/scoville/pgsql-ulid
- https://github.com/geckoboard/pgulid
-
@ e3ba5e1a:5e433365
2025-02-04 08:29:00
President Trump has started rolling out his tariffs, something I [blogged about in November](https://www.snoyman.com/blog/2024/11/steelmanning-tariffs/). People are talking about these tariffs a lot right now, with many people (correctly) commenting on how consumers will end up with higher prices as a result of these tariffs. While that part is true, I’ve seen a lot of people taking it to the next, incorrect step: that consumers will pay the entirety of the tax. I [put up a poll on X](https://x.com/snoyberg/status/1886035800019599808) to see what people thought, and while the right answer got a lot of votes, it wasn't the winner.
![image](https://yakihonne.s3.ap-east-1.amazonaws.com/e3ba5e1a06e11c860036b5c5e688012be2a84760abc066ac34a099535e433365/files/1738657292355-YAKIHONNES3.png)
For purposes of this blog post, our ultimate question will be the following:
* Suppose apples currently sell for $1 each in the entire United States.
* There are domestic sellers and foreign sellers of apples, all receiving the same price.
* There are no taxes or tariffs on the purchase of apples.
* The question is: if the US federal government puts a $0.50 import tariff per apple, what will be the change in the following:
* Number of apples bought in the US
* Price paid by buyers for apples in the US
* Post-tax price received by domestic apple producers
* Post-tax price received by foreign apple producers
Before we can answer that question, we need to ask an easier, first question: before instituting the tariff, why do apples cost $1?
And finally, before we dive into the details, let me provide you with the answers to the ultimate question. I recommend you try to guess these answers before reading this, and if you get it wrong, try to understand why:
1. The number of apples bought will go down
2. The buyers will pay more for each apple they buy, but not the full amount of the tariff
3. Domestic apple sellers will receive a *higher* price per apple
4. Foreign apple sellers will receive a *lower* price per apple, but not lowered by the full amount of the tariff
In other words, regardless of who sends the payment to the government, both taxed parties (domestic buyers and foreign sellers) will absorb some of the costs of the tariff, while domestic sellers will benefit from the protectionism provided by tariffs and be able to sell at a higher price per unit.
## Marginal benefit
All of the numbers discussed below are part of a [helper Google Sheet](https://docs.google.com/spreadsheets/d/14ZbkWpw1B9Q1UDB9Yh47DmdKQfIafVVBKbDUsSIfGZw/edit?usp=sharing) I put together for this analysis. Also, apologies about the jagged lines in the charts below, I hadn’t realized before starting on this that there are [some difficulties with creating supply and demand charts in Google Sheets](https://superuser.com/questions/1359731/how-to-create-a-supply-demand-style-chart).
Let’s say I absolutely love apples, they’re my favorite food. How much would I be willing to pay for a single apple? You might say “$1, that’s the price in the supermarket,” and in many ways you’d be right. If I walk into supermarket A, see apples on sale for $50, and know that I can buy them at supermarket B for $1, I’ll almost certainly leave A and go buy at B.
But that’s not what I mean. What I mean is: how high would the price of apples have to go *everywhere* so that I’d no longer be willing to buy a single apple? This is a purely personal, subjective opinion. It’s impacted by how much money I have available, other expenses I need to cover, and how much I like apples. But let’s say the number is $5.
How much would I be willing to pay for another apple? Maybe another $5. But how much am I willing to pay for the 1,000th apple? 10,000th? At some point, I’ll get sick of apples, or run out of space to keep the apples, or not be able to eat, cook, and otherwise preserve all those apples before they rot.
The point being: I’ll be progressively willing to spend less and less money for each apple. This form of analysis is called *marginal benefit*: how much benefit (expressed as dollars I’m willing to spend) will I receive from each apple? This is a downward sloping function: for each additional apple I buy (quantity demanded), the price I’m willing to pay goes down. This is what gives my personal *demand curve*. And if we aggregate demand curves across all market participants (meaning: everyone interested in buying apples), we end up with something like this:
![Demand curve before tax](https://www.snoyman.com/img/who-pays-tax/demand-before-tariff.png)
Assuming no changes in people’s behavior and other conditions in the market, this chart tells us how many apples will be purchased by our buyers at each price point between $0.50 and $5. And ceteris paribus (all else being equal), this will continue to be the demand curve for apples.
## Marginal cost
Demand is half the story of economics. The other half is supply, or: how many apples will I sell at each price point? Supply curves are upward sloping: the higher the price, the more a person or company is willing and able to sell a product.
Let’s understand why. Suppose I have an apple orchard. It’s a large property right next to my house. With about 2 minutes of effort, I can walk out of my house, find the nearest tree, pick 5 apples off the tree, and call it a day. 5 apples for 2 minutes of effort is pretty good, right?
Yes, there was all the effort necessary to buy the land, and plant the trees, and water them… and a bunch more than I likely can’t even guess at. We’re going to ignore all of that for our analysis, because for short-term supply-and-demand movement, we can ignore these kinds of *sunk costs*. One other simplification: in reality, supply curves often start descending before ascending. This accounts for achieving efficiencies of scale after the first number of units purchased. But since both these topics are unneeded for understanding taxes, I won’t go any further.
Anyway, back to my apple orchard. If someone offers me $0.50 per apple, I can do 2 minutes of effort and get $2.50 in revenue, which equates to a $75/hour wage for me. I’m more than happy to pick apples at that price\!
However, let’s say someone comes to buy 10,000 apples from me instead. I no longer just walk out to my nearest tree. I’m going to need to get in my truck, drive around, spend the day in the sun, pay for gas, take a day off of my day job (let’s say it pays me $70/hour). The costs go up significantly. Let’s say it takes 5 days to harvest all those apples myself, it costs me $100 in fuel and other expenses, and I lose out on my $70/hour job for 5 days. We end up with:
* Total expenditure: $100 \+ $70 \* 8 hours a day \* 5 days \== $2900
* Total revenue: $5000 (10,000 apples at $0.50 each)
* Total profit: $2100
So I’m still willing to sell the apples at this price, but it’s not as attractive as before. And as the number of apples purchased goes up, my costs keep increasing. I’ll need to spend more money on fuel to travel more of my property. At some point I won’t be able to do the work myself anymore, so I’ll need to pay others to work on the farm, and they’ll be slower at picking apples than me (less familiar with the property, less direct motivation, etc.). The point being: at some point, the number of apples can go high enough that the $0.50 price point no longer makes me any money.
This kind of analysis is called *marginal cost*. It refers to the additional amount of expenditure a seller has to spend in order to produce each additional unit of the good. Marginal costs go up as quantity sold goes up. And like demand curves, if you aggregate this data across all sellers, you get a supply curve like this:
![Supply curve before tariff](https://www.snoyman.com/img/who-pays-tax/supply-before-tariff.png)
## Equilibrium price
We now know, for every price point, how many apples buyers will purchase, and how many apples sellers will sell. Now we find the equilibrium: where the supply and demand curves meet. This point represents where the marginal benefit a buyer would receive from the next buyer would be less than the cost it would take the next seller to make it. Let’s see it in a chart:
![Supply and demand before tariff](https://www.snoyman.com/img/who-pays-tax/supply-demand-before-tariff.png)
You’ll notice that these two graphs cross at the $1 price point, where 63 apples are both demanded (bought by consumers) and supplied (sold by producers). This is our equilibrium price. We also have a visualization of the *surplus* created by these trades. Everything to the left of the equilibrium point and between the supply and demand curves represents surplus: an area where someone is receiving something of more value than they give. For example:
* When I bought my first apple for $1, but I was willing to spend $5, I made $4 of consumer surplus. The consumer portion of the surplus is everything to the left of the equilibrium point, between the supply and demand curves, and above the equilibrium price point.
* When a seller sells his first apple for $1, but it only cost $0.50 to produce it, the seller made $0.50 of producer surplus. The producer portion of the surplus is everything to the left of the equilibrium point, between the supply and demand curves, and below the equilibrium price point.
Another way of thinking of surplus is “every time someone got a better price than they would have been willing to take.”
OK, with this in place, we now have enough information to figure out how to price in the tariff, which we’ll treat as a negative externality.
## Modeling taxes
Alright, the government has now instituted a $0.50 tariff on every apple sold within the US by a foreign producer. We can generally model taxes by either increasing the marginal cost of each unit sold (shifting the supply curve up), or by decreasing the marginal benefit of each unit bought (shifting the demand curve down). In this case, since only some of the producers will pay the tax, it makes more sense to modify the supply curve.
First, let’s see what happens to the foreign seller-only supply curve when you add in the tariff:
![Foreign supply shift from tariff](https://www.snoyman.com/img/who-pays-tax/supply-tariff-shift.png)
With the tariff in place, for each quantity level, the price at which the seller will sell is $0.50 higher than before the tariff. That makes sense: if I was previously willing to sell my 82nd apple for $3, I would now need to charge $3.50 for that apple to cover the cost of the tariff. We see this as the tariff “pushing up” or “pushing left” the original supply curve.
We can add this new supply curve to our existing (unchanged) supply curve for domestic-only sellers, and we end up with a result like this:
![Supply curves post tariff](https://www.snoyman.com/img/who-pays-tax/supply-curves-post-tariff.png)
The total supply curve adds up the individual foreign and domestic supply curves. At each price point, we add up the total quantity each group would be willing to sell to determine the total quantity supplied for each price point. Once we have that cumulative supply curve defined, we can produce an updated supply-and-demand chart including the tariff:
![Supply and demand post tariff](https://www.snoyman.com/img/who-pays-tax/supply-demand-post-tariff.png)
As we can see, the equilibrium has shifted:
* The equilibrium price paid by consumers has risen from $1 to $1.20.
* The total number of apples purchased has dropped from 63 apples to 60 apples.
* Consumers therefore received 3 less apples. They spent $72 for these 60 apples, whereas previously they spent $63 for 3 more apples, a definite decrease in consumer surplus.
* Foreign producers sold 36 of those apples (see the raw data in the linked Google Sheet), for a gross revenue of $43.20. However, they also need to pay the tariff to the US government, which accounts for $18, meaning they only receive $25.20 post-tariff. Previously, they sold 42 apples at $1 each with no tariff to be paid, meaning they took home $42.
* Domestic producers sold the remaining 24 apples at $1.20, giving them a revenue of $28.80. Since they don’t pay the tariff, they take home all of that money. By contrast, previously, they sold 21 apples at $1, for a take-home of $21.
* The government receives $0.50 for each of the 60 apples sold, or in other words receives $30 in revenue it wouldn’t have received otherwise.
We could be more specific about the surpluses, and calculate the actual areas for consumer surplus, producer surplus, inefficiency from the tariff, and government revenue from the tariff. But I won’t bother, as those calculations get slightly more involved. Instead, let’s just look at the aggregate outcomes:
* Consumers were unquestionably hurt. Their price paid went up by $0.20 per apple, and received less apples.
* Foreign producers were also hurt. Their price received went down from the original $1 to the new post-tariff price of $1.20, minus the $0.50 tariff. In other words: foreign producers only receive $0.70 per apple now. This hurt can be mitigated by shifting sales to other countries without a tariff, but the pain will exist regardless.
* Domestic producers scored. They can sell less apples and make more revenue doing it.
* And the government walked away with an extra $30.
Hopefully you now see the answer to the original questions. Importantly, while the government imposed a $0.50 tariff, neither side fully absorbed that cost. Consumers paid a bit more, foreign producers received a bit less. The exact details of how that tariff was split across the groups is mediated by the relevant supply and demand curves of each group. If you want to learn more about this, the relevant search term is “price elasticity,” or how much a group’s quantity supplied or demanded will change based on changes in the price.
## Other taxes
Most taxes are some kind of a tax on trade. Tariffs on apples is an obvious one. But the same applies to income tax (taxing the worker for the trade of labor for money) or payroll tax (same thing, just taxing the employer instead). Interestingly, you can use the same model for analyzing things like tax incentives. For example, if the government decided to subsidize domestic apple production by giving the domestic producers a $0.50 bonus for each apple they sell, we would end up with a similar kind of analysis, except instead of the foreign supply curve shifting up, we’d see the domestic supply curve shifting down.
And generally speaking, this is what you’ll *always* see with government involvement in the economy. It will result in disrupting an existing equilibrium, letting the market readjust to a new equilibrium, and incentivization of some behavior, causing some people to benefit and others to lose out. We saw with the apple tariff, domestic producers and the government benefited while others lost.
You can see the reverse though with tax incentives. If I give a tax incentive of providing a deduction (not paying income tax) for preschool, we would end up with:
* Government needs to make up the difference in tax revenue, either by raising taxes on others or printing more money (leading to inflation). Either way, those paying the tax or those holding government debased currency will pay a price.
* Those people who don’t use the preschool deduction will receive no benefit, so they simply pay a cost.
* Those who do use the preschool deduction will end up paying less on tax+preschool than they would have otherwise.
This analysis is fully amoral. It’s not saying whether providing subsidized preschool is a good thing or not, it simply tells you where the costs will be felt, and points out that such government interference in free economic choice does result in inefficiencies in the system. Once you have that knowledge, you’re more well educated on making a decision about whether the costs of government intervention are worth the benefits.
-
@ 9e69e420:d12360c2
2025-02-01 11:16:04
![video]( https://service-pkgabcnews.akamaized.net/opp/hls/abcnews/2025/01/250128_abcnl_2p_dei_manager_hewlett_,500,800,1200,1800,2500,3200,4500,.mp4.csmil/playlist.m3u8)
Federal employees must remove pronouns from email signatures by the end of the day. This directive comes from internal memos tied to two executive orders signed by Donald Trump. The orders target diversity and equity programs within the government.
![image]( https://i.abcnewsfe.com/a/10eaacfd-9837-4b55-99a1-d3146c35cd3b/donald-trump-5-rt-gmh-250131_1738335513877_hpMain.jpg)
CDC, Department of Transportation, and Department of Energy employees were affected. Staff were instructed to make changes in line with revised policy prohibiting certain language.
One CDC employee shared frustration, stating, “In my decade-plus years at CDC, I've never been told what I can and can't put in my email signature.” The directive is part of a broader effort to eliminate DEI initiatives from federal discourse.
-
@ 97c70a44:ad98e322
2025-01-30 17:15:37
There was a slight dust up recently over a website someone runs removing a listing for an app someone built based on entirely arbitrary criteria. I'm not to going to attempt to speak for either wounded party, but I would like to share my own personal definition for what constitutes a "nostr app" in an effort to help clarify what might be an otherwise confusing and opaque purity test.
In this post, I will be committing the "no true Scotsman" fallacy, in which I start with the most liberal definition I can come up with, and gradually refine it until all that is left is the purest, gleamingest, most imaginary and unattainable nostr app imaginable. As I write this, I wonder if anything built yet will actually qualify. In any case, here we go.
# It uses nostr
The lowest bar for what a "nostr app" might be is an app ("application" - i.e. software, not necessarily a native app of any kind) that has some nostr-specific code in it, but which doesn't take any advantage of what makes nostr distinctive as a protocol.
Examples might include a scraper of some kind which fulfills its charter by fetching data from relays (regardless of whether it validates or retains signatures). Another might be a regular web 2.0 app which provides an option to "log in with nostr" by requesting and storing the user's public key.
In either case, the fact that nostr is involved is entirely neutral. A scraper can scrape html, pdfs, jsonl, whatever data source - nostr relays are just another target. Likewise, a user's key in this scenario is treated merely as an opaque identifier, with no appreciation for the super powers it brings along.
In most cases, this kind of app only exists as a marketing ploy, or less cynically, because it wants to get in on the hype of being a "nostr app", without the developer quite understanding what that means, or having the budget to execute properly on the claim.
# It leverages nostr
Some of you might be wondering, "isn't 'leverage' a synonym for 'use'?" And you would be right, but for one connotative difference. It's possible to "use" something improperly, but by definition leverage gives you a mechanical advantage that you wouldn't otherwise have. This is the second category of "nostr app".
This kind of app gets some benefit out of the nostr protocol and network, but in an entirely selfish fashion. The intention of this kind of app is not to augment the nostr network, but to augment its own UX by borrowing some nifty thing from the protocol without really contributing anything back.
Some examples might include:
- Using nostr signers to encrypt or sign data, and then store that data on a proprietary server.
- Using nostr relays as a kind of low-code backend, but using proprietary event payloads.
- Using nostr event kinds to represent data (why), but not leveraging the trustlessness that buys you.
An application in this category might even communicate to its users via nostr DMs - but this doesn't make it a "nostr app" any more than a website that emails you hot deals on herbal supplements is an "email app". These apps are purely parasitic on the nostr ecosystem.
In the long-term, that's not necessarily a bad thing. Email's ubiquity is self-reinforcing. But in the short term, this kind of "nostr app" can actually do damage to nostr's reputation by over-promising and under-delivering.
# It complements nostr
Next up, we have apps that get some benefit out of nostr as above, but give back by providing a unique value proposition to nostr users as nostr users. This is a bit of a fine distinction, but for me this category is for apps which focus on solving problems that nostr isn't good at solving, leaving the nostr integration in a secondary or supporting role.
One example of this kind of app was Mutiny (RIP), which not only allowed users to sign in with nostr, but also pulled those users' social graphs so that users could send money to people they knew and trusted. Mutiny was doing a great job of leveraging nostr, as well as providing value to users with nostr identities - but it was still primarily a bitcoin wallet, not a "nostr app" in the purest sense.
Other examples are things like Nostr Nests and Zap.stream, whose core value proposition is streaming video or audio content. Both make great use of nostr identities, data formats, and relays, but they're primarily streaming apps. A good litmus test for things like this is: if you got rid of nostr, would it be the same product (even if inferior in certain ways)?
A similar category is infrastructure providers that benefit nostr by their existence (and may in fact be targeted explicitly at nostr users), but do things in a centralized, old-web way; for example: media hosts, DNS registrars, hosting providers, and CDNs.
To be clear here, I'm not casting aspersions (I don't even know what those are, or where to buy them). All the apps mentioned above use nostr to great effect, and are a real benefit to nostr users. But they are not True Scotsmen.
# It embodies nostr
Ok, here we go. This is the crème de la crème, the top du top, the meilleur du meilleur, the bee's knees. The purest, holiest, most chaste category of nostr app out there. The apps which are, indeed, nostr indigitate.
This category of nostr app (see, no quotes this time) can be defined by the converse of the previous category. If nostr was removed from this type of application, would it be impossible to create the same product?
To tease this apart a bit, apps that leverage the technical aspects of nostr are dependent on nostr the *protocol*, while apps that benefit nostr exclusively via network effect are integrated into nostr the *network*. An app that does both things is working in symbiosis with nostr as a whole.
An app that embraces both nostr's protocol and its network becomes an organic extension of every other nostr app out there, multiplying both its competitive moat and its contribution to the ecosystem:
- In contrast to apps that only borrow from nostr on the technical level but continue to operate in their own silos, an application integrated into the nostr network comes pre-packaged with existing users, and is able to provide more value to those users because of other nostr products. On nostr, it's a good thing to advertise your competitors.
- In contrast to apps that only market themselves to nostr users without building out a deep integration on the protocol level, a deeply integrated app becomes an asset to every other nostr app by becoming an organic extension of them through interoperability. This results in increased traffic to the app as other developers and users refer people to it instead of solving their problem on their own. This is the "micro-apps" utopia we've all been waiting for.
Credible exit doesn't matter if there aren't alternative services. Interoperability is pointless if other applications don't offer something your app doesn't. Marketing to nostr users doesn't matter if you don't augment their agency _as nostr users_.
If I had to choose a single NIP that represents the mindset behind this kind of app, it would be NIP 89 A.K.A. "Recommended Application Handlers", which states:
> Nostr's discoverability and transparent event interaction is one of its most interesting/novel mechanics. This NIP provides a simple way for clients to discover applications that handle events of a specific kind to ensure smooth cross-client and cross-kind interactions.
These handlers are the glue that holds nostr apps together. A single event, signed by the developer of an application (or by the application's own account) tells anyone who wants to know 1. what event kinds the app supports, 2. how to link to the app (if it's a client), and (if the pubkey also publishes a kind 10002), 3. which relays the app prefers.
_As a sidenote, NIP 89 is currently focused more on clients, leaving DVMs, relays, signers, etc somewhat out in the cold. Updating 89 to include tailored listings for each kind of supporting app would be a huge improvement to the protocol. This, plus a good front end for navigating these listings (sorry nostrapp.link, close but no cigar) would obviate the evil centralized websites that curate apps based on arbitrary criteria._
Examples of this kind of app obviously include many kind 1 clients, as well as clients that attempt to bring the benefits of the nostr protocol and network to new use cases - whether long form content, video, image posts, music, emojis, recipes, project management, or any other "content type".
To drill down into one example, let's think for a moment about forms. What's so great about a forms app that is built on nostr? Well,
- There is a [spec](https://github.com/nostr-protocol/nips/pull/1190) for forms and responses, which means that...
- Multiple clients can implement the same data format, allowing for credible exit and user choice, even of...
- Other products not focused on forms, which can still view, respond to, or embed forms, and which can send their users via NIP 89 to a client that does...
- Cryptographically sign forms and responses, which means they are self-authenticating and can be sent to...
- Multiple relays, which reduces the amount of trust necessary to be confident results haven't been deliberately "lost".
Show me a forms product that does all of those things, and isn't built on nostr. You can't, because it doesn't exist. Meanwhile, there are plenty of image hosts with APIs, streaming services, and bitcoin wallets which have basically the same levels of censorship resistance, interoperability, and network effect as if they weren't built on nostr.
# It supports nostr
Notice I haven't said anything about whether relays, signers, blossom servers, software libraries, DVMs, and the accumulated addenda of the nostr ecosystem are nostr apps. Well, they are (usually).
This is the category of nostr app that gets none of the credit for doing all of the work. There's no question that they qualify as beautiful nostrcorns, because their value propositions are entirely meaningless outside of the context of nostr. Who needs a signer if you don't have a cryptographic identity you need to protect? DVMs are literally impossible to use without relays. How are you going to find the blossom server that will serve a given hash if you don't know which servers the publishing user has selected to store their content?
In addition to being entirely contextualized by nostr architecture, this type of nostr app is valuable because it does things "the nostr way". By that I mean that they don't simply try to replicate existing internet functionality into a nostr context; instead, they create entirely new ways of putting the basic building blocks of the internet back together.
A great example of this is how Nostr Connect, Nostr Wallet Connect, and DVMs all use relays as brokers, which allows service providers to avoid having to accept incoming network connections. This opens up really interesting possibilities all on its own.
So while I might hesitate to call many of these things "apps", they are certainly "nostr".
# Appendix: it smells like a NINO
So, let's say you've created an app, but when you show it to people they politely smile, nod, and call it a NINO (Nostr In Name Only). What's a hacker to do? Well, here's your handy-dandy guide on how to wash that NINO stench off and Become a Nostr.
You app might be a NINO if:
- There's no NIP for your data format (or you're abusing NIP 78, 32, etc by inventing a sub-protocol inside an existing event kind)
- There's a NIP, but no one knows about it because it's in a text file on your hard drive (or buried in your project's repository)
- Your NIP imposes an incompatible/centralized/legacy web paradigm onto nostr
- Your NIP relies on trusted third (or first) parties
- There's only one implementation of your NIP (yours)
- Your core value proposition doesn't depend on relays, events, or nostr identities
- One or more relay urls are hard-coded into the source code
- Your app depends on a specific relay implementation to work (*ahem*, relay29)
- You don't validate event signatures
- You don't publish events to relays you don't control
- You don't read events from relays you don't control
- You use legacy web services to solve problems, rather than nostr-native solutions
- You use nostr-native solutions, but you've hardcoded their pubkeys or URLs into your app
- You don't use NIP 89 to discover clients and services
- You haven't published a NIP 89 listing for your app
- You don't leverage your users' web of trust for filtering out spam
- You don't respect your users' mute lists
- You try to "own" your users' data
Now let me just re-iterate - it's ok to be a NINO. We need NINOs, because nostr can't (and shouldn't) tackle every problem. You just need to decide whether your app, as a NINO, is actually contributing to the nostr ecosystem, or whether you're just using buzzwords to whitewash a legacy web software product.
If you're in the former camp, great! If you're in the latter, what are you waiting for? Only you can fix your NINO problem. And there are lots of ways to do this, depending on your own unique situation:
- Drop nostr support if it's not doing anyone any good. If you want to build a normal company and make some money, that's perfectly fine.
- Build out your nostr integration - start taking advantage of webs of trust, self-authenticating data, event handlers, etc.
- Work around the problem. Think you need a special relay feature for your app to work? Guess again. Consider encryption, AUTH, DVMs, or better data formats.
- Think your idea is a good one? Talk to other devs or open a PR to the [nips repo](https://github.com/nostr-protocol/nips). No one can adopt your NIP if they don't know about it.
- Keep going. It can sometimes be hard to distinguish a research project from a NINO. New ideas have to be built out before they can be fully appreciated.
- Listen to advice. Nostr developers are friendly and happy to help. If you're not sure why you're getting traction, ask!
I sincerely hope this article is useful for all of you out there in NINO land. Maybe this made you feel better about not passing the totally optional nostr app purity test. Or maybe it gave you some actionable next steps towards making a great NINON (Nostr In Not Only Name) app. In either case, GM and PV.
-
@ 9e69e420:d12360c2
2025-01-30 12:23:04
Tech stocks have taken a hit globally after China's DeepSeek launched a competitive AI chatbot at a much lower cost than US counterparts. This has stirred market fears of a $1.2 trillion loss across tech companies when trading opens in New York.
DeepSeek’s chatbot quickly topped download charts and surprised experts with its capabilities, developed for only $5.6 million.
The Nasdaq dropped over 3% in premarket trading, with major firms like Nvidia falling more than 10%. SoftBank also saw losses shortly after investing in a significant US AI venture.
Venture capitalist Marc Andreessen called it “AI’s Sputnik moment,” highlighting its potential impact on the industry.
![] (https://www.telegraph.co.uk/content/dam/business/2025/01/27/TELEMMGLPICT000409807198_17379939060750_trans_NvBQzQNjv4BqgsaO8O78rhmZrDxTlQBjdGLvJF5WfpqnBZShRL_tOZw.jpeg)
-
@ 9e69e420:d12360c2
2025-01-30 12:13:39
Salwan Momika, a Christian Iraqi known for burning the Koran in Sweden, was shot dead during a TikTok livestream in an apartment in Sodertalje. The 38-year-old sparked outrage in the Muslim community for his demonstrations, leading to global condemnation. After being rushed to the hospital, he was pronounced dead.
Authorities arrested five individuals in connection with the incident. Momika's death comes days before a court ruling on his possible incitement of ethnic hatred. The incident highlights the tensions surrounding free speech and religious sentiments, intensifying after his controversial protests in 2023.
[Sauce](https://www.dailymail.co.uk/news/article-14341423/Christian-Iraqi-burnt-Koran-Sweden-shot-dead.html)
-
@ 0fa80bd3:ea7325de
2025-01-30 04:28:30
**"Degeneration"** or **"Вырождение"**
![[photo_2025-01-29 23.23.15.jpeg]]
A once-functional object, now eroded by time and human intervention, stripped of its original purpose. Layers of presence accumulate—marks, alterations, traces of intent—until the very essence is obscured. Restoration is paradoxical: to reclaim, one must erase. Yet erasure is an impossibility, for to remove these imprints is to deny the existence of those who shaped them.
The work stands as a meditation on entropy, memory, and the irreversible dialogue between creation and decay.
-
@ 0fa80bd3:ea7325de
2025-01-29 15:43:42
Lyn Alden - биткойн евангелист или евангелистка, я пока не понял
```
npub1a2cww4kn9wqte4ry70vyfwqyqvpswksna27rtxd8vty6c74era8sdcw83a
```
Thomas Pacchia - PubKey owner - X - @tpacchia
```
npub1xy6exlg37pw84cpyj05c2pdgv86hr25cxn0g7aa8g8a6v97mhduqeuhgpl
```
calvadev - Shopstr
```
npub16dhgpql60vmd4mnydjut87vla23a38j689jssaqlqqlzrtqtd0kqex0nkq
```
Calle - Cashu founder
```
npub12rv5lskctqxxs2c8rf2zlzc7xx3qpvzs3w4etgemauy9thegr43sf485vg
```
Джек Дорси
```
npub1sg6plzptd64u62a878hep2kev88swjh3tw00gjsfl8f237lmu63q0uf63m
```
21 ideas
```
npub1lm3f47nzyf0rjp6fsl4qlnkmzed4uj4h2gnf2vhe3l3mrj85vqks6z3c7l
```
Много адресов. Хз кто надо сортировать
```
https://github.com/aitechguy/nostr-address-book
```
ФиатДжеф - создатель Ностр - https://github.com/fiatjaf
```
npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6
```
EVAN KALOUDIS Zues wallet
```
npub19kv88vjm7tw6v9qksn2y6h4hdt6e79nh3zjcud36k9n3lmlwsleqwte2qd
```
Программер Коди https://github.com/CodyTseng/nostr-relay
```
npub1syjmjy0dp62dhccq3g97fr87tngvpvzey08llyt6ul58m2zqpzps9wf6wl
```
Anna Chekhovich - Managing Bitcoin at The Anti-Corruption Foundation
https://x.com/AnyaChekhovich
```
npub1y2st7rp54277hyd2usw6shy3kxprnmpvhkezmldp7vhl7hp920aq9cfyr7
```
-
@ 0fa80bd3:ea7325de
2025-01-29 14:44:48
![[yedinaya-rossiya-bear.png]]
1️⃣ Be where the bear roams. Stay in its territory, where it hunts for food. No point setting a trap in your backyard if the bear’s chilling in the forest.
2️⃣ Set a well-hidden trap. Bury it, disguise it, and place the bait right in the center. Bears are omnivores—just like secret police KGB agents. And what’s the tastiest bait for them? Money.
3️⃣ Wait for the bear to take the bait. When it reaches in, the trap will snap shut around its paw. It’ll be alive, but stuck. No escape.
Now, what you do with a trapped bear is another question... 😏
-
@ 0fa80bd3:ea7325de
2025-01-29 05:55:02
The land that belongs to the indigenous peoples of Russia has been seized by a gang of killers who have unleashed a war of extermination. They wipe out anyone who refuses to conform to their rules. Those who disagree and stay behind are tortured and killed in prisons and labor camps. Those who flee lose their homeland, dissolve into foreign cultures, and fade away. And those who stand up to protect their people are attacked by the misled and deceived. The deceived die for the unchecked greed of a single dictator—thousands from both sides, people who just wanted to live, raise their kids, and build a future.
Now, they are forced to make an impossible choice: abandon their homeland or die. Some perish on the battlefield, others lose themselves in exile, stripped of their identity, scattered in a world that isn’t theirs.
There’s been endless debate about how to fix this, how to clear the field of the weeds that choke out every new sprout, every attempt at change. But the real problem? We can’t play by their rules. We can’t speak their language or use their weapons. We stand for humanity, and no matter how righteous our cause, we will not multiply suffering. Victory doesn’t come from matching the enemy—it comes from staying ahead, from using tools they haven’t mastered yet. That’s how wars are won.
Our only resource is the **will of the people** to rewrite the order of things. Historian Timothy Snyder once said that a nation cannot exist without a city. A city is where the most active part of a nation thrives. But the cities are occupied. The streets are watched. Gatherings are impossible. They control the money. They control the mail. They control the media. And any dissent is crushed before it can take root.
So I started asking myself: **How do we stop this fragmentation?** How do we create a space where people can **rebuild their connections** when they’re ready? How do we build a **self-sustaining network**, where everyone contributes and benefits proportionally, while keeping their freedom to leave intact? And more importantly—**how do we make it spread, even in occupied territory?**
In 2009, something historic happened: **the internet got its own money.** Thanks to **Satoshi Nakamoto**, the world took a massive leap forward. Bitcoin and decentralized ledgers shattered the idea that money must be controlled by the state. Now, to move or store value, all you need is an address and a key. A tiny string of text, easy to carry, impossible to seize.
That was the year money broke free. The state lost its grip. Its biggest weapon—physical currency—became irrelevant. Money became **purely digital.**
The internet was already **a sanctuary for information**, a place where people could connect and organize. But with Bitcoin, it evolved. Now, **value itself** could flow freely, beyond the reach of authorities.
Think about it: when seedlings are grown in controlled environments before being planted outside, they **get stronger, survive longer, and bear fruit faster.** That’s how we handle crops in harsh climates—nurture them until they’re ready for the wild.
Now, picture the internet as that **controlled environment** for **ideas**. Bitcoin? It’s the **fertile soil** that lets them grow. A testing ground for new models of interaction, where concepts can take root before they move into the real world. If **nation-states are a battlefield, locked in a brutal war for territory, the internet is boundless.** It can absorb any number of ideas, any number of people, and it doesn’t **run out of space.**
But for this ecosystem to thrive, people need safe ways to communicate, to share ideas, to build something real—**without surveillance, without censorship, without the constant fear of being erased.**
This is where **Nostr** comes in.
Nostr—"Notes and Other Stuff Transmitted by Relays"—is more than just a messaging protocol. **It’s a new kind of city.** One that **no dictator can seize**, no corporation can own, no government can shut down.
It’s built on **decentralization, encryption, and individual control.** Messages don’t pass through central servers—they are relayed through independent nodes, and users choose which ones to trust. There’s no master switch to shut it all down. Every person owns their identity, their data, their connections. And no one—no state, no tech giant, no algorithm—can silence them.
In a world where cities fall and governments fail, **Nostr is a city that cannot be occupied.** A place for ideas, for networks, for freedom. A city that grows stronger **the more people build within it**.
-
@ 9e69e420:d12360c2
2025-01-26 15:26:44
Secretary of State Marco Rubio issued new guidance halting spending on most foreign aid grants for 90 days, including military assistance to Ukraine. This immediate order shocked State Department officials and mandates “stop-work orders” on nearly all existing foreign assistance awards.
While it allows exceptions for military financing to Egypt and Israel, as well as emergency food assistance, it restricts aid to key allies like Ukraine, Jordan, and Taiwan. The guidance raises potential liability risks for the government due to unfulfilled contracts.
A report will be prepared within 85 days to recommend which programs to continue or discontinue.
-
@ 9e69e420:d12360c2
2025-01-26 01:31:31
## Chef's notes
# arbitray
- test
- of
- chefs notes
## hedding 2
## Details
- ⏲️ Prep time: 20
- 🍳 Cook time: 1 hour
- 🍽️ Servings: 5
## Ingredients
- Test ingredient
- 2nd test ingredient
## Directions
1. Bake
2. Cool
-
@ 9e69e420:d12360c2
2025-01-25 22:16:54
President Trump plans to withdraw 20,000 U.S. troops from Europe and expects European allies to contribute financially to the remaining military presence. Reported by ANSA, Trump aims to deliver this message to European leaders since taking office. A European diplomat noted, “the costs cannot be borne solely by American taxpayers.”
The Pentagon hasn't commented yet. Trump has previously sought lower troop levels in Europe and had ordered cuts during his first term. The U.S. currently maintains around 65,000 troops in Europe, with total forces reaching 100,000 since the Ukraine invasion. Trump's new approach may shift military focus to the Pacific amid growing concerns about China.
[Sauce](https://www.stripes.com/theaters/europe/2025-01-24/trump-europe-troop-cuts-16590074.html)
-
@ 6be5cc06:5259daf0
2025-01-21 20:58:37
A seguir, veja como instalar e configurar o **Privoxy** no **Pop!_OS**.
---
### **1. Instalar o Tor e o Privoxy**
Abra o terminal e execute:
```bash
sudo apt update
sudo apt install tor privoxy
```
**Explicação:**
- **Tor:** Roteia o tráfego pela rede Tor.
- **Privoxy:** Proxy avançado que intermedia a conexão entre aplicativos e o Tor.
---
### **2. Configurar o Privoxy**
Abra o arquivo de configuração do Privoxy:
```bash
sudo nano /etc/privoxy/config
```
Navegue até a última linha (atalho: **`Ctrl`** + **`/`** depois **`Ctrl`** + **`V`** para navegar diretamente até a última linha) e insira:
```bash
forward-socks5 / 127.0.0.1:9050 .
```
Isso faz com que o **Privoxy** envie todo o tráfego para o **Tor** através da porta **9050**.
Salve (**`CTRL`** + **`O`** e **`Enter`**) e feche (**`CTRL`** + **`X`**) o arquivo.
---
### **3. Iniciar o Tor e o Privoxy**
Agora, inicie e habilite os serviços:
```bash
sudo systemctl start tor
sudo systemctl start privoxy
sudo systemctl enable tor
sudo systemctl enable privoxy
```
**Explicação:**
- **start:** Inicia os serviços.
- **enable:** Faz com que iniciem automaticamente ao ligar o PC.
---
### **4. Configurar o Navegador Firefox**
Para usar a rede **Tor** com o Firefox:
1. Abra o Firefox.
2. Acesse **Configurações** → **Configurar conexão**.
3. Selecione **Configuração manual de proxy**.
4. Configure assim:
- **Proxy HTTP:** `127.0.0.1`
- **Porta:** `8118` (porta padrão do **Privoxy**)
- **Domínio SOCKS (v5):** `127.0.0.1`
- **Porta:** `9050`
5. Marque a opção **"Usar este proxy também em HTTPS"**.
6. Clique em **OK**.
---
### **5. Verificar a Conexão com o Tor**
Abra o navegador e acesse:
```text
https://check.torproject.org/
```
Se aparecer a mensagem **"Congratulations. This browser is configured to use Tor."**, a configuração está correta.
---
### **Dicas Extras**
- **Privoxy** pode ser ajustado para bloquear anúncios e rastreadores.
- Outros aplicativos também podem ser configurados para usar o **Privoxy**.
-
@ 9e69e420:d12360c2
2025-01-21 19:31:48
Oregano oil is a potent natural compound that offers numerous scientifically-supported health benefits.
## Active Compounds
The oil's therapeutic properties stem from its key bioactive components:
- Carvacrol and thymol (primary active compounds)
- Polyphenols and other antioxidant
## Antimicrobial Properties
**Bacterial Protection**
The oil demonstrates powerful antibacterial effects, even against antibiotic-resistant strains like MRSA and other harmful bacteria. Studies show it effectively inactivates various pathogenic bacteria without developing resistance.
**Antifungal Effects**
It effectively combats fungal infections, particularly Candida-related conditions like oral thrush, athlete's foot, and nail infections.
## Digestive Health Benefits
Oregano oil supports digestive wellness by:
- Promoting gastric juice secretion and enzyme production
- Helping treat Small Intestinal Bacterial Overgrowth (SIBO)
- Managing digestive discomfort, bloating, and IBS symptoms
## Anti-inflammatory and Antioxidant Effects
The oil provides significant protective benefits through:
- Powerful antioxidant activity that fights free radicals
- Reduction of inflammatory markers in the body
- Protection against oxidative stress-related conditions
## Respiratory Support
It aids respiratory health by:
- Loosening mucus and phlegm
- Suppressing coughs and throat irritation
- Supporting overall respiratory tract function
## Additional Benefits
**Skin Health**
- Improves conditions like psoriasis, acne, and eczema
- Supports wound healing through antibacterial action
- Provides anti-aging benefits through antioxidant properties
**Cardiovascular Health**
Studies show oregano oil may help:
- Reduce LDL (bad) cholesterol levels
- Support overall heart health
**Pain Management**
The oil demonstrates effectiveness in:
- Reducing inflammation-related pain
- Managing muscle discomfort
- Providing topical pain relief
## Safety Note
While oregano oil is generally safe, it's highly concentrated and should be properly diluted before use Consult a healthcare provider before starting supplementation, especially if taking other medications.
-
@ b17fccdf:b7211155
2025-01-21 17:02:21
The past 26 August, Tor [introduced officially](https://blog.torproject.org/introducing-proof-of-work-defense-for-onion-services/) a proof-of-work (PoW) defense for onion services designed to prioritize verified network traffic as a deterrent against denial of service (DoS) attacks.
~ > This feature at the moment, is [deactivate by default](https://gitlab.torproject.org/tpo/core/tor/-/blob/main/doc/man/tor.1.txt#L3117), so you need to follow these steps to activate this on a MiniBolt node:
* Make sure you have the latest version of Tor installed, at the time of writing this post, which is v0.4.8.6. Check your current version by typing
```
tor --version
```
**Example** of expected output:
```
Tor version 0.4.8.6.
This build of Tor is covered by the GNU General Public License (https://www.gnu.org/licenses/gpl-3.0.en.html)
Tor is running on Linux with Libevent 2.1.12-stable, OpenSSL 3.0.9, Zlib 1.2.13, Liblzma 5.4.1, Libzstd N/A and Glibc 2.36 as libc.
Tor compiled with GCC version 12.2.0
```
~ > If you have v0.4.8.X, you are **OK**, if not, type `sudo apt update && sudo apt upgrade` and confirm to update.
* Basic PoW support can be checked by running this command:
```
tor --list-modules
```
Expected output:
```
relay: yes
dirauth: yes
dircache: yes
pow: **yes**
```
~ > If you have `pow: yes`, you are **OK**
* Now go to the torrc file of your MiniBolt and add the parameter to enable PoW for each hidden service added
```
sudo nano /etc/tor/torrc
```
Example:
```
# Hidden Service BTC RPC Explorer
HiddenServiceDir /var/lib/tor/hidden_service_btcrpcexplorer/
HiddenServiceVersion 3
HiddenServicePoWDefensesEnabled 1
HiddenServicePort 80 127.0.0.1:3002
```
~ > Bitcoin Core and LND use the Tor control port to automatically create the hidden service, requiring no action from the user. We have submitted a feature request in the official GitHub repositories to explore the need for the integration of Tor's PoW defense into the automatic creation process of the hidden service. You can follow them at the following links:
* Bitcoin Core: https://github.com/lightningnetwork/lnd/issues/8002
* LND: https://github.com/bitcoin/bitcoin/issues/28499
---
More info:
* https://blog.torproject.org/introducing-proof-of-work-defense-for-onion-services/
* https://gitlab.torproject.org/tpo/onion-services/onion-support/-/wikis/Documentation/PoW-FAQ
---
Enjoy it MiniBolter! 💙
-
@ 6be5cc06:5259daf0
2025-01-21 01:51:46
## Bitcoin: Um sistema de dinheiro eletrônico direto entre pessoas.
Satoshi Nakamoto
satoshin@gmx.com
www.bitcoin.org
---
### Resumo
O Bitcoin é uma forma de dinheiro digital que permite pagamentos diretos entre pessoas, sem a necessidade de um banco ou instituição financeira. Ele resolve um problema chamado **gasto duplo**, que ocorre quando alguém tenta gastar o mesmo dinheiro duas vezes. Para evitar isso, o Bitcoin usa uma rede descentralizada onde todos trabalham juntos para verificar e registrar as transações.
As transações são registradas em um livro público chamado **blockchain**, protegido por uma técnica chamada **Prova de Trabalho**. Essa técnica cria uma cadeia de registros que não pode ser alterada sem refazer todo o trabalho já feito. Essa cadeia é mantida pelos computadores que participam da rede, e a mais longa é considerada a verdadeira.
Enquanto a maior parte do poder computacional da rede for controlada por participantes honestos, o sistema continuará funcionando de forma segura. A rede é flexível, permitindo que qualquer pessoa entre ou saia a qualquer momento, sempre confiando na cadeia mais longa como prova do que aconteceu.
---
### 1. Introdução
Hoje, quase todos os pagamentos feitos pela internet dependem de bancos ou empresas como processadores de pagamento (cartões de crédito, por exemplo) para funcionar. Embora esse sistema seja útil, ele tem problemas importantes porque é baseado em **confiança**.
Primeiro, essas empresas podem reverter pagamentos, o que é útil em caso de erros, mas cria custos e incertezas. Isso faz com que pequenas transações, como pagar centavos por um serviço, se tornem inviáveis. Além disso, os comerciantes são obrigados a desconfiar dos clientes, pedindo informações extras e aceitando fraudes como algo inevitável.
Esses problemas não existem no dinheiro físico, como o papel-moeda, onde o pagamento é final e direto entre as partes. No entanto, não temos como enviar dinheiro físico pela internet sem depender de um intermediário confiável.
O que precisamos é de um **sistema de pagamento eletrônico baseado em provas matemáticas**, não em confiança. Esse sistema permitiria que qualquer pessoa enviasse dinheiro diretamente para outra, sem depender de bancos ou processadores de pagamento. Além disso, as transações seriam irreversíveis, protegendo vendedores contra fraudes, mas mantendo a possibilidade de soluções para disputas legítimas.
Neste documento, apresentamos o **Bitcoin**, que resolve o problema do gasto duplo usando uma rede descentralizada. Essa rede cria um registro público e protegido por cálculos matemáticos, que garante a ordem das transações. Enquanto a maior parte da rede for controlada por pessoas honestas, o sistema será seguro contra ataques.
---
### 2. Transações
Para entender como funciona o Bitcoin, é importante saber como as transações são realizadas. Imagine que você quer transferir uma "moeda digital" para outra pessoa. No sistema do Bitcoin, essa "moeda" é representada por uma sequência de registros que mostram quem é o atual dono. Para transferi-la, você adiciona um novo registro comprovando que agora ela pertence ao próximo dono. Esse registro é protegido por um tipo especial de assinatura digital.
#### O que é uma assinatura digital?
Uma assinatura digital é como uma senha secreta, mas muito mais segura. No Bitcoin, cada usuário tem duas chaves: uma "chave privada", que é secreta e serve para criar a assinatura, e uma "chave pública", que pode ser compartilhada com todos e é usada para verificar se a assinatura é válida. Quando você transfere uma moeda, usa sua chave privada para assinar a transação, provando que você é o dono. A próxima pessoa pode usar sua chave pública para confirmar isso.
#### Como funciona na prática?
Cada "moeda" no Bitcoin é, na verdade, uma cadeia de assinaturas digitais. Vamos imaginar o seguinte cenário:
1. A moeda está com o Dono 0 (você). Para transferi-la ao Dono 1, você assina digitalmente a transação com sua chave privada. Essa assinatura inclui o código da transação anterior (chamado de "hash") e a chave pública do Dono 1.
2. Quando o Dono 1 quiser transferir a moeda ao Dono 2, ele assinará a transação seguinte com sua própria chave privada, incluindo também o hash da transação anterior e a chave pública do Dono 2.
3. Esse processo continua, formando uma "cadeia" de transações. Qualquer pessoa pode verificar essa cadeia para confirmar quem é o atual dono da moeda.
#### Resolvendo o problema do gasto duplo
Um grande desafio com moedas digitais é o "gasto duplo", que é quando uma mesma moeda é usada em mais de uma transação. Para evitar isso, muitos sistemas antigos dependiam de uma entidade central confiável, como uma casa da moeda, que verificava todas as transações. No entanto, isso criava um ponto único de falha e centralizava o controle do dinheiro.
O Bitcoin resolve esse problema de forma inovadora: ele usa uma rede descentralizada onde todos os participantes (os "nós") têm acesso a um registro completo de todas as transações. Cada nó verifica se as transações são válidas e se a moeda não foi gasta duas vezes. Quando a maioria dos nós concorda com a validade de uma transação, ela é registrada permanentemente na blockchain.
#### Por que isso é importante?
Essa solução elimina a necessidade de confiar em uma única entidade para gerenciar o dinheiro, permitindo que qualquer pessoa no mundo use o Bitcoin sem precisar de permissão de terceiros. Além disso, ela garante que o sistema seja seguro e resistente a fraudes.
---
### 3. Servidor Timestamp
Para assegurar que as transações sejam realizadas de forma segura e transparente, o sistema Bitcoin utiliza algo chamado de "servidor de registro de tempo" (timestamp). Esse servidor funciona como um registro público que organiza as transações em uma ordem específica.
Ele faz isso agrupando várias transações em blocos e criando um código único chamado "hash". Esse hash é como uma impressão digital que representa todo o conteúdo do bloco. O hash de cada bloco é amplamente divulgado, como se fosse publicado em um jornal ou em um fórum público.
Esse processo garante que cada bloco de transações tenha um registro de quando foi criado e que ele existia naquele momento. Além disso, cada novo bloco criado contém o hash do bloco anterior, formando uma cadeia contínua de blocos conectados — conhecida como blockchain.
Com isso, se alguém tentar alterar qualquer informação em um bloco anterior, o hash desse bloco mudará e não corresponderá ao hash armazenado no bloco seguinte. Essa característica torna a cadeia muito segura, pois qualquer tentativa de fraude seria imediatamente detectada.
O sistema de timestamps é essencial para provar a ordem cronológica das transações e garantir que cada uma delas seja única e autêntica. Dessa forma, ele reforça a segurança e a confiança na rede Bitcoin.
---
### 4. Prova-de-Trabalho
Para implementar o registro de tempo distribuído no sistema Bitcoin, utilizamos um mecanismo chamado prova-de-trabalho. Esse sistema é semelhante ao Hashcash, desenvolvido por Adam Back, e baseia-se na criação de um código único, o "hash", por meio de um processo computacionalmente exigente.
A prova-de-trabalho envolve encontrar um valor especial que, quando processado junto com as informações do bloco, gere um hash que comece com uma quantidade específica de zeros. Esse valor especial é chamado de "nonce". Encontrar o nonce correto exige um esforço significativo do computador, porque envolve tentativas repetidas até que a condição seja satisfeita.
Esse processo é importante porque torna extremamente difícil alterar qualquer informação registrada em um bloco. Se alguém tentar mudar algo em um bloco, seria necessário refazer o trabalho de computação não apenas para aquele bloco, mas também para todos os blocos que vêm depois dele. Isso garante a segurança e a imutabilidade da blockchain.
A prova-de-trabalho também resolve o problema de decidir qual cadeia de blocos é a válida quando há múltiplas cadeias competindo. A decisão é feita pela cadeia mais longa, pois ela representa o maior esforço computacional já realizado. Isso impede que qualquer indivíduo ou grupo controle a rede, desde que a maioria do poder de processamento seja mantida por participantes honestos.
Para garantir que o sistema permaneça eficiente e equilibrado, a dificuldade da prova-de-trabalho é ajustada automaticamente ao longo do tempo. Se novos blocos estiverem sendo gerados rapidamente, a dificuldade aumenta; se estiverem sendo gerados muito lentamente, a dificuldade diminui. Esse ajuste assegura que novos blocos sejam criados aproximadamente a cada 10 minutos, mantendo o sistema estável e funcional.
---
### 5. Rede
A rede Bitcoin é o coração do sistema e funciona de maneira distribuída, conectando vários participantes (ou nós) para garantir o registro e a validação das transações. Os passos para operar essa rede são:
1. **Transmissão de Transações**: Quando alguém realiza uma nova transação, ela é enviada para todos os nós da rede. Isso é feito para garantir que todos estejam cientes da operação e possam validá-la.
2. **Coleta de Transações em Blocos**: Cada nó agrupa as novas transações recebidas em um "bloco". Este bloco será preparado para ser adicionado à cadeia de blocos (a blockchain).
3. **Prova-de-Trabalho**: Os nós competem para resolver a prova-de-trabalho do bloco, utilizando poder computacional para encontrar um hash válido. Esse processo é como resolver um quebra-cabeça matemático difícil.
4. **Envio do Bloco Resolvido**: Quando um nó encontra a solução para o bloco (a prova-de-trabalho), ele compartilha esse bloco com todos os outros nós na rede.
5. **Validação do Bloco**: Cada nó verifica o bloco recebido para garantir que todas as transações nele contidas sejam válidas e que nenhuma moeda tenha sido gasta duas vezes. Apenas blocos válidos são aceitos.
6. **Construção do Próximo Bloco**: Os nós que aceitaram o bloco começam a trabalhar na criação do próximo bloco, utilizando o hash do bloco aceito como base (hash anterior). Isso mantém a continuidade da cadeia.
#### Resolução de Conflitos e Escolha da Cadeia Mais Longa
Os nós sempre priorizam a cadeia mais longa, pois ela representa o maior esforço computacional já realizado, garantindo maior segurança. Se dois blocos diferentes forem compartilhados simultaneamente, os nós trabalharão no primeiro bloco recebido, mas guardarão o outro como uma alternativa. Caso o segundo bloco eventualmente forme uma cadeia mais longa (ou seja, tenha mais blocos subsequentes), os nós mudarão para essa nova cadeia.
#### Tolerância a Falhas
A rede é robusta e pode lidar com mensagens que não chegam a todos os nós. Uma transação não precisa alcançar todos os nós de imediato; basta que chegue a um número suficiente deles para ser incluída em um bloco. Da mesma forma, se um nó não receber um bloco em tempo hábil, ele pode solicitá-lo ao perceber que está faltando quando o próximo bloco é recebido.
Esse mecanismo descentralizado permite que a rede Bitcoin funcione de maneira segura, confiável e resiliente, sem depender de uma autoridade central.
---
### 6. Incentivo
O incentivo é um dos pilares fundamentais que sustenta o funcionamento da rede Bitcoin, garantindo que os participantes (nós) continuem operando de forma honesta e contribuindo com recursos computacionais. Ele é estruturado em duas partes principais: a recompensa por mineração e as taxas de transação.
#### Recompensa por Mineração
Por convenção, o primeiro registro em cada bloco é uma transação especial que cria novas moedas e as atribui ao criador do bloco. Essa recompensa incentiva os mineradores a dedicarem poder computacional para apoiar a rede. Como não há uma autoridade central para emitir moedas, essa é a maneira pela qual novas moedas entram em circulação. Esse processo pode ser comparado ao trabalho de garimpeiros, que utilizam recursos para colocar mais ouro em circulação. No caso do Bitcoin, o "recurso" consiste no tempo de CPU e na energia elétrica consumida para resolver a prova-de-trabalho.
#### Taxas de Transação
Além da recompensa por mineração, os mineradores também podem ser incentivados pelas taxas de transação. Se uma transação utiliza menos valor de saída do que o valor de entrada, a diferença é tratada como uma taxa, que é adicionada à recompensa do bloco contendo essa transação. Com o passar do tempo e à medida que o número de moedas em circulação atinge o limite predeterminado, essas taxas de transação se tornam a principal fonte de incentivo, substituindo gradualmente a emissão de novas moedas. Isso permite que o sistema opere sem inflação, uma vez que o número total de moedas permanece fixo.
#### Incentivo à Honestidade
O design do incentivo também busca garantir que os participantes da rede mantenham um comportamento honesto. Para um atacante que consiga reunir mais poder computacional do que o restante da rede, ele enfrentaria duas escolhas:
1. Usar esse poder para fraudar o sistema, como reverter transações e roubar pagamentos.
2. Seguir as regras do sistema, criando novos blocos e recebendo recompensas legítimas.
A lógica econômica favorece a segunda opção, pois um comportamento desonesto prejudicaria a confiança no sistema, diminuindo o valor de todas as moedas, incluindo aquelas que o próprio atacante possui. Jogar dentro das regras não apenas maximiza o retorno financeiro, mas também preserva a validade e a integridade do sistema.
Esse mecanismo garante que os incentivos econômicos estejam alinhados com o objetivo de manter a rede segura, descentralizada e funcional ao longo do tempo.
---
### 7. Recuperação do Espaço em Disco
Depois que uma moeda passa a estar protegida por muitos blocos na cadeia, as informações sobre as transações antigas que a geraram podem ser descartadas para economizar espaço em disco. Para que isso seja possível sem comprometer a segurança, as transações são organizadas em uma estrutura chamada "árvore de Merkle". Essa árvore funciona como um resumo das transações: em vez de armazenar todas elas, guarda apenas um "hash raiz", que é como uma assinatura compacta que representa todo o grupo de transações.
Os blocos antigos podem, então, ser simplificados, removendo as partes desnecessárias dessa árvore. Apenas a raiz do hash precisa ser mantida no cabeçalho do bloco, garantindo que a integridade dos dados seja preservada, mesmo que detalhes específicos sejam descartados.
Para exemplificar: imagine que você tenha vários recibos de compra. Em vez de guardar todos os recibos, você cria um documento e lista apenas o valor total de cada um. Mesmo que os recibos originais sejam descartados, ainda é possível verificar a soma com base nos valores armazenados.
Além disso, o espaço ocupado pelos blocos em si é muito pequeno. Cada bloco sem transações ocupa apenas cerca de 80 bytes. Isso significa que, mesmo com blocos sendo gerados a cada 10 minutos, o crescimento anual em espaço necessário é insignificante: apenas 4,2 MB por ano. Com a capacidade de armazenamento dos computadores crescendo a cada ano, esse espaço continuará sendo trivial, garantindo que a rede possa operar de forma eficiente sem problemas de armazenamento, mesmo a longo prazo.
---
### 8. Verificação de Pagamento Simplificada
É possível confirmar pagamentos sem a necessidade de operar um nó completo da rede. Para isso, o usuário precisa apenas de uma cópia dos cabeçalhos dos blocos da cadeia mais longa (ou seja, a cadeia com maior esforço de trabalho acumulado). Ele pode verificar a validade de uma transação ao consultar os nós da rede até obter a confirmação de que tem a cadeia mais longa. Para isso, utiliza-se o ramo Merkle, que conecta a transação ao bloco em que ela foi registrada.
Entretanto, o método simplificado possui limitações: ele não pode confirmar uma transação isoladamente, mas sim assegurar que ela ocupa um lugar específico na cadeia mais longa. Dessa forma, se um nó da rede aprova a transação, os blocos subsequentes reforçam essa aceitação.
A verificação simplificada é confiável enquanto a maioria dos nós da rede for honesta. Contudo, ela se torna vulnerável caso a rede seja dominada por um invasor. Nesse cenário, um atacante poderia fabricar transações fraudulentas que enganariam o usuário temporariamente até que o invasor obtivesse controle completo da rede.
Uma estratégia para mitigar esse risco é configurar alertas nos softwares de nós completos. Esses alertas identificam blocos inválidos, sugerindo ao usuário baixar o bloco completo para confirmar qualquer inconsistência. Para maior segurança, empresas que realizam pagamentos frequentes podem preferir operar seus próprios nós, reduzindo riscos e permitindo uma verificação mais direta e confiável.
---
### 9. Combinando e Dividindo Valor
No sistema Bitcoin, cada unidade de valor é tratada como uma "moeda" individual, mas gerenciar cada centavo como uma transação separada seria impraticável. Para resolver isso, o Bitcoin permite que valores sejam combinados ou divididos em transações, facilitando pagamentos de qualquer valor.
#### Entradas e Saídas
Cada transação no Bitcoin é composta por:
- **Entradas**: Representam os valores recebidos em transações anteriores.
- **Saídas**: Correspondem aos valores enviados, divididos entre os destinatários e, eventualmente, o troco para o remetente.
Normalmente, uma transação contém:
- Uma única entrada com valor suficiente para cobrir o pagamento.
- Ou várias entradas combinadas para atingir o valor necessário.
O valor total das saídas nunca excede o das entradas, e a diferença (se houver) pode ser retornada ao remetente como **troco**.
#### Exemplo Prático
Imagine que você tem duas entradas:
1. 0,03 BTC
2. 0,07 BTC
Se deseja enviar 0,08 BTC para alguém, a transação terá:
- **Entrada**: As duas entradas combinadas (0,03 + 0,07 BTC = 0,10 BTC).
- **Saídas**: Uma para o destinatário (0,08 BTC) e outra como troco para você (0,02 BTC).
Essa flexibilidade permite que o sistema funcione sem precisar manipular cada unidade mínima individualmente.
#### Difusão e Simplificação
A difusão de transações, onde uma depende de várias anteriores e assim por diante, não representa um problema. Não é necessário armazenar ou verificar o histórico completo de uma transação para utilizá-la, já que o registro na blockchain garante sua integridade.
---
### 10. Privacidade
O modelo bancário tradicional oferece um certo nível de privacidade, limitando o acesso às informações financeiras apenas às partes envolvidas e a um terceiro confiável (como bancos ou instituições financeiras). No entanto, o Bitcoin opera de forma diferente, pois todas as transações são publicamente registradas na blockchain. Apesar disso, a privacidade pode ser mantida utilizando **chaves públicas anônimas**, que desvinculam diretamente as transações das identidades das partes envolvidas.
#### Fluxo de Informação
- No **modelo tradicional**, as transações passam por um terceiro confiável que conhece tanto o remetente quanto o destinatário.
- No **Bitcoin**, as transações são anunciadas publicamente, mas sem revelar diretamente as identidades das partes. Isso é comparável a dados divulgados por bolsas de valores, onde informações como o tempo e o tamanho das negociações (a "fita") são públicas, mas as identidades das partes não.
#### Protegendo a Privacidade
Para aumentar a privacidade no Bitcoin, são adotadas as seguintes práticas:
1. **Chaves Públicas Anônimas**: Cada transação utiliza um par de chaves diferentes, dificultando a associação com um proprietário único.
2. **Prevenção de Ligação**: Ao usar chaves novas para cada transação, reduz-se a possibilidade de links evidentes entre múltiplas transações realizadas pelo mesmo usuário.
#### Riscos de Ligação
Embora a privacidade seja fortalecida, alguns riscos permanecem:
- Transações **multi-entrada** podem revelar que todas as entradas pertencem ao mesmo proprietário, caso sejam necessárias para somar o valor total.
- O proprietário da chave pode ser identificado indiretamente por transações anteriores que estejam conectadas.
---
### 11. Cálculos
Imagine que temos um sistema onde as pessoas (ou computadores) competem para adicionar informações novas (blocos) a um grande registro público (a cadeia de blocos ou blockchain). Este registro é como um livro contábil compartilhado, onde todos podem verificar o que está escrito.
Agora, vamos pensar em um cenário: um atacante quer enganar o sistema. Ele quer mudar informações já registradas para beneficiar a si mesmo, por exemplo, desfazendo um pagamento que já fez. Para isso, ele precisa criar uma versão alternativa do livro contábil (a cadeia de blocos dele) e convencer todos os outros participantes de que essa versão é a verdadeira.
Mas isso é extremamente difícil.
#### Como o Ataque Funciona
Quando um novo bloco é adicionado à cadeia, ele depende de cálculos complexos que levam tempo e esforço. Esses cálculos são como um grande quebra-cabeça que precisa ser resolvido.
- Os “bons jogadores” (nós honestos) estão sempre trabalhando juntos para resolver esses quebra-cabeças e adicionar novos blocos à cadeia verdadeira.
- O atacante, por outro lado, precisa resolver quebra-cabeças sozinho, tentando “alcançar” a cadeia honesta para que sua versão alternativa pareça válida.
Se a cadeia honesta já está vários blocos à frente, o atacante começa em desvantagem, e o sistema está projetado para que a dificuldade de alcançá-los aumente rapidamente.
#### A Corrida Entre Cadeias
Você pode imaginar isso como uma corrida. A cada bloco novo que os jogadores honestos adicionam à cadeia verdadeira, eles se distanciam mais do atacante. Para vencer, o atacante teria que resolver os quebra-cabeças mais rápido que todos os outros jogadores honestos juntos.
Suponha que:
- A rede honesta tem **80% do poder computacional** (ou seja, resolve 8 de cada 10 quebra-cabeças).
- O atacante tem **20% do poder computacional** (ou seja, resolve 2 de cada 10 quebra-cabeças).
Cada vez que a rede honesta adiciona um bloco, o atacante tem que "correr atrás" e resolver mais quebra-cabeças para alcançar.
#### Por Que o Ataque Fica Cada Vez Mais Improvável?
Vamos usar uma fórmula simples para mostrar como as chances de sucesso do atacante diminuem conforme ele precisa "alcançar" mais blocos:
P = (q/p)^z
- **q** é o poder computacional do atacante (20%, ou 0,2).
- **p** é o poder computacional da rede honesta (80%, ou 0,8).
- **z** é a diferença de blocos entre a cadeia honesta e a cadeia do atacante.
Se o atacante está 5 blocos atrás (z = 5):
P = (0,2 / 0,8)^5 = (0,25)^5 = 0,00098, (ou, 0,098%)
Isso significa que o atacante tem menos de 0,1% de chance de sucesso — ou seja, é muito improvável.
Se ele estiver 10 blocos atrás (z = 10):
P = (0,2 / 0,8)^10 = (0,25)^10 = 0,000000095, (ou, 0,0000095%).
Neste caso, as chances de sucesso são praticamente **nulas**.
#### Um Exemplo Simples
Se você jogar uma moeda, a chance de cair “cara” é de 50%. Mas se precisar de 10 caras seguidas, sua chance já é bem menor. Se precisar de 20 caras seguidas, é quase impossível.
No caso do Bitcoin, o atacante precisa de muito mais do que 20 caras seguidas. Ele precisa resolver quebra-cabeças extremamente difíceis e alcançar os jogadores honestos que estão sempre à frente. Isso faz com que o ataque seja inviável na prática.
#### Por Que Tudo Isso é Seguro?
- **A probabilidade de sucesso do atacante diminui exponencialmente.** Isso significa que, quanto mais tempo passa, menor é a chance de ele conseguir enganar o sistema.
- **A cadeia verdadeira (honesta) está protegida pela força da rede.** Cada novo bloco que os jogadores honestos adicionam à cadeia torna mais difícil para o atacante alcançar.
#### E Se o Atacante Tentar Continuar?
O atacante poderia continuar tentando indefinidamente, mas ele estaria gastando muito tempo e energia sem conseguir nada. Enquanto isso, os jogadores honestos estão sempre adicionando novos blocos, tornando o trabalho do atacante ainda mais inútil.
Assim, o sistema garante que a cadeia verdadeira seja extremamente segura e que ataques sejam, na prática, impossíveis de ter sucesso.
---
### 12. Conclusão
Propusemos um sistema de transações eletrônicas que elimina a necessidade de confiança, baseando-se em assinaturas digitais e em uma rede peer-to-peer que utiliza prova de trabalho. Isso resolve o problema do gasto duplo, criando um histórico público de transações imutável, desde que a maioria do poder computacional permaneça sob controle dos participantes honestos.
A rede funciona de forma simples e descentralizada, com nós independentes que não precisam de identificação ou coordenação direta. Eles entram e saem livremente, aceitando a cadeia de prova de trabalho como registro do que ocorreu durante sua ausência. As decisões são tomadas por meio do poder de CPU, validando blocos legítimos, estendendo a cadeia e rejeitando os inválidos.
Com este mecanismo de consenso, todas as regras e incentivos necessários para o funcionamento seguro e eficiente do sistema são garantidos.
---
Faça o download do whitepaper original em português:
https://bitcoin.org/files/bitcoin-paper/bitcoin_pt_br.pdf
-
@ 3f770d65:7a745b24
2025-01-19 21:48:49
The recent shutdown of TikTok in the United States due to a potential government ban serves as a stark reminder how fragile centralized platforms truly are under the surface. While these platforms offer convenience, a more polished user experience, and connectivity, they are ultimately beholden to governments, corporations, and other authorities. This makes them vulnerable to censorship, regulation, and outright bans. In contrast, Nostr represents a shift in how we approach online communication and content sharing. Built on the principles of decentralization and user choice, Nostr cannot be banned, because it is not a platform—it is a protocol.
**PROTOCOLS, NOT PLATFORMS.**
At the heart of Nostr's philosophy is **user choice**, a feature that fundamentally sets it apart from legacy platforms. In centralized systems, the user experience is dictated by a single person or governing entity. If the platform decides to filter, censor, or ban specific users or content, individuals are left with little action to rectify the situation. They must either accept the changes or abandon the platform entirely, often at the cost of losing their social connections, their data, and their identity.
What's happening with TikTok could never happen on Nostr. With Nostr, the dynamics are completely different. Because it is a protocol, not a platform, no single entity controls the ecosystem. Instead, the protocol enables a network of applications and relays that users can freely choose from. If a particular application or relay implements policies that a user disagrees with, such as censorship, filtering, or even government enforced banning, they are not trapped or abandoned. They have the freedom to move to another application or relay with minimal effort.
**THIS IS POWERFUL.**
Take, for example, the case of a relay that decides to censor specific content. On a legacy platform, this would result in frustration and a loss of access for users. On Nostr, however, users can simply connect to a different relay that does not impose such restrictions. Similarly, if an application introduces features or policies that users dislike, they can migrate to a different application that better suits their preferences, all while retaining their identity and social connections.
The same principles apply to government bans and censorship. A government can ban a specific application or even multiple applications, just as it can block one relay or several relays. China has implemented both tactics, yet Chinese users continue to exist and actively participate on Nostr, demonstrating Nostr's ability to resistant censorship.
How? Simply, it turns into a game of whack-a-mole. When one relay is censored, another quickly takes its place. When one application is banned, another emerges. Users can also bypass these obstacles by running their own relays and applications directly from their homes or personal devices, eliminating reliance on larger entities or organizations and ensuring continuous access.
**AGAIN, THIS IS POWERUFL.**
Nostr's open and decentralized design makes it resistant to the kinds of government intervention that led to TikTok's outages this weekend and potential future ban in the next 90 days. There is no central server to target, no company to regulate, and no single point of failure. (Insert your CEO jokes here). As long as there are individuals running relays and applications, users continue creating notes and sending zaps.
Platforms like TikTok can be silenced with the stroke of a pen, leaving millions of users disconnected and abandoned. Social communication should not be silenced so incredibly easily. No one should have that much power over social interactions.
Will we on-board a massive wave of TikTokers in the coming hours or days? I don't know.
TikTokers may not be ready for Nostr yet, and honestly, Nostr may not be ready for them either. The ecosystem still lacks the completely polished applications, tools, and services they’re accustomed to. This is where we say "we're still early". They may not be early adopters like the current Nostr user base. Until we bridge that gap, they’ll likely move to the next centralized platform, only to face another government ban or round of censorship in the future. But eventually, there will come a tipping point, a moment when they’ve had enough. When that time comes, I hope we’re prepared. If we’re not, we risk missing a tremendous opportunity to onboard people who genuinely need Nostr’s freedom.
Until then, to all of the Nostr developers out there, keep up the great work and keep building. Your hard work and determination is needed.
###
-
@ cff1720e:15c7e2b2
2025-01-19 17:48:02
**Einleitung**\
\
Schwierige Dinge einfach zu erklären ist der Anspruch von ELI5 (explain me like I'm 5). Das ist in unserer hoch technisierten Welt dringend erforderlich, denn nur mit dem Verständnis der Technologien können wir sie richtig einsetzen und weiter entwickeln.\
Ich starte meine Serie mit Nostr, einem relativ neuen Internet-Protokoll. Was zum Teufel ist ein Internet-Protokoll? Formal beschrieben sind es internationale Standards, die dafür sorgen, dass das Internet seit über 30 Jahren ziemlich gut funktioniert. Es ist die Sprache, in der sich die Rechner miteinander unterhalten und die auch Sie täglich nutzen, vermutlich ohne es bewusst wahrzunehmen. http(s) transportiert ihre Anfrage an einen Server (z.B. Amazon), und html sorgt dafür, dass aus den gelieferten Daten eine schöne Seite auf ihrem Bildschirm entsteht. Eine Mail wird mit smtp an den Mailserver gesendet und mit imap von ihm abgerufen, und da alle den Standard verwenden, funktioniert das mit jeder App auf jedem Betriebssystem und mit jedem Mail-Provider. Und mit einer Mail-Adresse wie <roland@pareto.space> können sie sogar jederzeit umziehen, egal wohin. **Cool, das ist state of the art!** Aber warum funktioniert das z.B. bei Chat nicht, gibt es da kein Protokoll? Doch, es heißt IRC (Internet Relay Chat → merken sie sich den Namen), aber es wird so gut wie nicht verwendet. Die Gründe dafür sind nicht technischer Natur, vielmehr wurden mit Apps wie Facebook, Twitter, WhatsApp, Telegram, Instagram, TikTok u.a. bewusst Inkompatibilitäten und Nutzerabhängigkeiten geschaffen um Profite zu maximieren.
![1.00](https://route96.pareto.space/766f49ae2a2da2138a9cb2977aa508a526842ce5eb1d3fa74f3b7e9fc590e30f.png)
**Warum Nostr?**
Da das Standard-Protokoll nicht genutzt wird, hat jede App ihr eigenes, und wir brauchen eine handvoll Apps um uns mit allen Bekannten auszutauschen. Eine Mobilfunknummer ist Voraussetzung für jedes Konto, damit können die App-Hersteller die Nutzer umfassend tracken und mit dem Verkauf der Informationen bis zu 30 USD je Konto und Monat verdienen. Der Nutzer ist nicht mehr Kunde, er ist das Produkt! Der Werbe-SPAM ist noch das kleinste Problem bei diesem Geschäftsmodell. Server mit Millionen von Nutzerdaten sind ein “honey pot”, dementsprechend oft werden sie gehackt und die Zugangsdaten verkauft. 2024 wurde auch der Twitter-Account vom damaligen Präsidenten Joe Biden gehackt, niemand wusste mehr wer die Nachrichten verfasst hat (vorher auch nicht), d.h. die Authentizität der Inhalte ist bei keinem dieser Anbieter gewährleistet. Im selben Jahr wurde der Telegram-Gründer in Frankreich in Beugehaft genommen, weil er sich geweigert hatte Hintertüren in seine Software einzubauen. Nun kann zum Schutz **"unserer Demokratie”** praktisch jeder mitlesen, was sie mit wem an Informationen austauschen, z.B. darüber welches Shampoo bestimmte Politiker verwenden.
![1.00](https://cdn.nostrcheck.me/cff1720e77bb068f0ebbd389dcd50822dd1ac8d2ac0b0f5f0800ae9e15c7e2b2/a4e859b0a89ed91cc2da575225a98529647de3b202fe639e3f919a09eeacd8b5.webp)
Und wer tatsächlich glaubt er könne Meinungsfreiheit auf sozialen Medien praktizieren, findet sich schnell in der Situation von Donald Trump wieder (seinerzeit amtierender Präsident), dem sein Twitter-Konto 2021 abgeschaltet wurde (Cancel-Culture). Die Nutzerdaten, also ihr Profil, ihre Kontakte, Dokumente, Bilder, Videos und Audiofiles - gehören ihnen ohnehin nicht mehr sondern sind Eigentum des Plattform-Betreibers; lesen sie sich mal die AGB's durch. Aber nein, keine gute Idee, das sind hunderte Seiten und sie werden permanent geändert. Alle nutzen also Apps, deren Technik sie nicht verstehen, deren Regeln sie nicht kennen, wo sie keine Rechte haben und die ihnen die Resultate ihres Handelns stehlen. Was würde wohl der Fünfjährige sagen, wenn ihm seine ältere Schwester anbieten würde, alle seine Spielzeuge zu “verwalten” und dann auszuhändigen wenn er brav ist? “Du spinnst wohl”, und damit beweist der Knirps mehr Vernunft als die Mehrzahl der Erwachsenen. \
\
**Resümee:** keine Standards, keine Daten, keine Rechte = keine Zukunft!
![1.00](https://cdn.nostrcheck.me/cff1720e77bb068f0ebbd389dcd50822dd1ac8d2ac0b0f5f0800ae9e15c7e2b2/03e526e8f288b66580d1eeff3002d57094a0bdc36198c920af026f4ef32caeba.webp)
\
**Wie funktioniert Nostr?**
Die Entwickler von Nostr haben erkannt dass sich das Server-Client-Konzept in ein Master-Slave-Konzept verwandelt hatte. Der Master ist ein Synonym für Zentralisierung und wird zum **“single point of failure”**, der zwangsläufig Systeme dysfunktional macht. In einem verteilten Peer2Peer-System gibt es keine Master mehr sondern nur gleichberechtigte Knoten (Relays), auf denen die Informationen gespeichert werden. Indem man Informationen auf mehreren Relays redundant speichert, ist das System in jeglicher Hinsicht resilienter. Nicht nur die Natur verwendet dieses Prinzip seit Jahrmillionen erfolgreich, auch das Internet wurde so konzipiert (das ARPAnet wurde vom US-Militär für den Einsatz in Kriegsfällen unter massiven Störungen entwickelt). Alle Nostr-Daten liegen auf Relays und der Nutzer kann wählen zwischen öffentlichen (zumeist kostenlosen) und privaten Relays, z.B. für geschlossene Gruppen oder zum Zwecke von Daten-Archivierung. Da Dokumente auf mehreren Relays gespeichert sind, werden statt URL's (Locator) eindeutige Dokumentnamen (URI's = Identifier) verwendet, broken Links sind damit Vergangenheit und Löschungen / Verluste ebenfalls.\
\
Jedes Dokument (Event genannt) wird vom Besitzer signiert, es ist damit authentisch und fälschungssicher und kann nur vom Ersteller gelöscht werden. Dafür wird ein Schlüsselpaar verwendet bestehend aus privatem (nsec) und öffentlichem Schlüssel (npub) wie aus der Mailverschlüsselung (PGP) bekannt. Das repräsentiert eine Nostr-Identität, die um Bild, Namen, Bio und eine lesbare Nostr-Adresse ergänzt werden kann (z.B. <roland@pareto.space> ), mehr braucht es nicht um alle Ressourcen des Nostr-Ökosystems zu nutzen. Und das besteht inzwischen aus über hundert Apps mit unterschiedlichen Fokussierungen, z.B. für persönliche verschlüsselte Nachrichten (DM → OxChat), Kurznachrichten (Damus, Primal), Blogbeiträge (Pareto), Meetups (Joinstr), Gruppen (Groups), Bilder (Olas), Videos (Amethyst), Audio-Chat (Nostr Nests), Audio-Streams (Tunestr), Video-Streams (Zap.Stream), Marktplätze (Shopstr) u.v.a.m. Die Anmeldung erfolgt mit einem Klick (single sign on) und den Apps stehen ALLE Nutzerdaten zur Verfügung (Profil, Daten, Kontakte, Social Graph → Follower, Bookmarks, Comments, etc.), im Gegensatz zu den fragmentierten Datensilos der Gegenwart.\
\
**Resümee:** ein offener Standard, alle Daten, alle Rechte = große Zukunft!
![1.00](https://cdn.nostrcheck.me/cff1720e77bb068f0ebbd389dcd50822dd1ac8d2ac0b0f5f0800ae9e15c7e2b2/e95b593c37e2fbc0946cb5658c12784737176ca83548cd1d843de19fe82bcc26.webp)
\
**Warum ist Nostr die Zukunft des Internet?**
“Baue Dein Haus nicht auf einem fremden Grundstück” gilt auch im Internet - für alle App-Entwickler, Künstler, Journalisten und Nutzer, denn auch ihre Daten sind werthaltig. Nostr garantiert das Eigentum an den Daten, und überwindet ihre Fragmentierung. Weder die Nutzung noch die kreativen Freiheiten werden durch maßlose Lizenz- und Nutzungsbedingungen eingeschränkt. Aus passiven Nutzern werden durch Interaktion aktive Teilnehmer, Co-Creatoren in einer Sharing-Ökonomie **(Value4Value)**. OpenSource schafft endlich wieder Vertrauen in die Software und ihre Anbieter. Offene Standards ermöglichen den Entwicklern mehr Kooperation und schnellere Entwicklung, für die Anwender garantieren sie Wahlfreiheit. Womit wir letztmalig zu unserem Fünfjährigen zurückkehren. Kinder lieben Lego über alles, am meisten die Maxi-Box “Classic”, weil sie damit ihre Phantasie im Kombinieren voll ausleben können. Erwachsene schenken ihnen dann die viel zu teuren Themenpakete, mit denen man nur eine Lösung nach Anleitung bauen kann. “Was stimmt nur mit meinen Eltern nicht, wann sind die denn falsch abgebogen?" fragt sich der Nachwuchs zu Recht. Das Image lässt sich aber wieder aufpolieren, wenn sie ihren Kindern Nostr zeigen, denn die Vorteile verstehen sogar Fünfjährige.
![1.00](https://cdn.nostrcheck.me/cff1720e77bb068f0ebbd389dcd50822dd1ac8d2ac0b0f5f0800ae9e15c7e2b2/44a62a737a26a79c5772b630f8b5d109167064662b43dd4ed38d9e5e26c2a184.webp)
\
**Das neue Internet ist dezentral. Das neue Internet ist selbstbestimmt. Nostr ist das neue Internet.**
<https://nostr.net/> \
<https://start.njump.me/>
**Hier das Interview zum Thema mit Radio Berliner Morgenröte**
<https://www.podbean.com/ew/pb-yxc36-17bb4be>
-
@ 9e69e420:d12360c2
2025-01-19 04:48:31
A new report from the National Sports Shooting Foundation (NSSF) shows that civilian firearm possession exceeded 490 million in 2022. The total from 1990 to 2022 is estimated at 491.3 million firearms. In 2022, over ten million firearms were domestically produced, leading to a total of 16,045,911 firearms available in the U.S. market.
Of these, 9,873,136 were handguns, 4,195,192 were rifles, and 1,977,583 were shotguns. Handgun availability aligns with the concealed carry and self-defense market, as all states allow concealed carry, with 29 having constitutional carry laws.
-
@ f9cf4e94:96abc355
2025-01-18 06:09:50
Para esse exemplo iremos usar:
| Nome | Imagem | Descrição |
| --------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| Raspberry PI B+ | ![]( https://embarcados.com.br/wp-content/uploads/2014/07/imagem-de-destaque-1-1.png) | **Cortex-A53 (ARMv8) 64-bit a 1.4GHz e 1 GB de SDRAM LPDDR2,** |
| Pen drive | ![]( https://m.media-amazon.com/images/I/61ERDR3tATL.jpg) | **16Gb** |
Recomendo que use o **Ubuntu Server** para essa instalação. Você pode baixar o Ubuntu para Raspberry Pi [aqui]( https://ubuntu.com/download/raspberry-pi). O passo a passo para a instalação do Ubuntu no Raspberry Pi está disponível [aqui]( https://ubuntu.com/tutorials/how-to-install-ubuntu-on-your-raspberry-pi). **Não instale um desktop** (como xubuntu, lubuntu, xfce, etc.).
---
## Passo 1: Atualizar o Sistema 🖥️
Primeiro, atualize seu sistema e instale o Tor:
```bash
apt update
apt install tor
```
---
## Passo 2: Criar o Arquivo de Serviço `nrs.service` 🔧
Crie o arquivo de serviço que vai gerenciar o servidor Nostr. Você pode fazer isso com o seguinte conteúdo:
```unit
[Unit]
Description=Nostr Relay Server Service
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/nrs
ExecStart=/opt/nrs/nrs-arm64
Restart=on-failure
[Install]
WantedBy=multi-user.target
```
---
## Passo 3: Baixar o Binário do Nostr 🚀
Baixe o binário mais recente do Nostr [aqui no GitHub]( https://github.com/gabrielmoura/SimpleNosrtRelay/releases).
---
## Passo 4: Criar as Pastas Necessárias 📂
Agora, crie as pastas para o aplicativo e o pendrive:
```bash
mkdir -p /opt/nrs /mnt/edriver
```
---
## Passo 5: Listar os Dispositivos Conectados 🔌
Para saber qual dispositivo você vai usar, liste todos os dispositivos conectados:
```bash
lsblk
```
---
## Passo 6: Formatando o Pendrive 💾
Escolha o pendrive correto (por exemplo, `/dev/sda`) e formate-o:
```bash
mkfs.vfat /dev/sda
```
---
## Passo 7: Montar o Pendrive 💻
Monte o pendrive na pasta `/mnt/edriver`:
```bash
mount /dev/sda /mnt/edriver
```
---
## Passo 8: Verificar UUID dos Dispositivos 📋
Para garantir que o sistema monte o pendrive automaticamente, liste os UUID dos dispositivos conectados:
```bash
blkid
```
---
## Passo 9: Alterar o `fstab` para Montar o Pendrive Automáticamente 📝
Abra o arquivo `/etc/fstab` e adicione uma linha para o pendrive, com o UUID que você obteve no passo anterior. A linha deve ficar assim:
```fstab
UUID=9c9008f8-f852 /mnt/edriver vfat defaults 0 0
```
---
## Passo 10: Copiar o Binário para a Pasta Correta 📥
Agora, copie o binário baixado para a pasta `/opt/nrs`:
```bash
cp nrs-arm64 /opt/nrs
```
---
## Passo 11: Criar o Arquivo de Configuração 🛠️
Crie o arquivo de configuração com o seguinte conteúdo e salve-o em `/opt/nrs/config.yaml`:
```yaml
app_env: production
info:
name: Nostr Relay Server
description: Nostr Relay Server
pub_key: ""
contact: ""
url: http://localhost:3334
icon: https://external-content.duckduckgo.com/iu/?u= https://public.bnbstatic.com/image/cms/crawler/COINCU_NEWS/image-495-1024x569.png
base_path: /mnt/edriver
negentropy: true
```
---
## Passo 12: Copiar o Serviço para o Diretório de Systemd ⚙️
Agora, copie o arquivo `nrs.service` para o diretório `/etc/systemd/system/`:
```bash
cp nrs.service /etc/systemd/system/
```
Recarregue os serviços e inicie o serviço `nrs`:
```bash
systemctl daemon-reload
systemctl enable --now nrs.service
```
---
## Passo 13: Configurar o Tor 🌐
Abra o arquivo de configuração do Tor `/var/lib/tor/torrc` e adicione a seguinte linha:
```torrc
HiddenServiceDir /var/lib/tor/nostr_server/
HiddenServicePort 80 127.0.0.1:3334
```
---
## Passo 14: Habilitar e Iniciar o Tor 🧅
Agora, ative e inicie o serviço Tor:
```bash
systemctl enable --now tor.service
```
O Tor irá gerar um endereço `.onion` para o seu servidor Nostr. Você pode encontrá-lo no arquivo `/var/lib/tor/nostr_server/hostname`.
---
## Observações ⚠️
- Com essa configuração, **os dados serão salvos no pendrive**, enquanto o binário ficará no cartão SD do Raspberry Pi.
- O endereço `.onion` do seu servidor Nostr será algo como: `ws://y3t5t5wgwjif<exemplo>h42zy7ih6iwbyd.onion`.
---
Agora, seu servidor Nostr deve estar configurado e funcionando com Tor! 🥳
Se este artigo e as informações aqui contidas forem úteis para você, convidamos a considerar uma doação ao autor como forma de reconhecimento e incentivo à produção de novos conteúdos.
-
@ 6389be64:ef439d32
2025-01-16 15:44:06
## Black Locust can grow up to 170 ft tall
## Grows 3-4 ft. per year
## Native to North America
## Cold hardy in zones 3 to 8
![image](https://yakihonne.s3.ap-east-1.amazonaws.com/6389be6491e7b693e9f368ece88fcd145f07c068d2c1bbae4247b9b5ef439d32/files/1736980729189-YAKIHONNES3.jpg)
## Firewood
- BLT wood, on a pound for pound basis is roughly half that of Anthracite Coal
- Since its growth is fast, firewood can be plentiful
## Timber
![image](https://yakihonne.s3.ap-east-1.amazonaws.com/6389be6491e7b693e9f368ece88fcd145f07c068d2c1bbae4247b9b5ef439d32/files/1736980782258-YAKIHONNES3.jpg)
- Rot resistant due to a naturally produced robinin in the wood
- 100 year life span in full soil contact! (better than cedar performance)
- Fence posts
- Outdoor furniture
- Outdoor decking
- Sustainable due to its fast growth and spread
- Can be coppiced (cut to the ground)
- Can be pollarded (cut above ground)
- Its dense wood makes durable tool handles, boxes (tool), and furniture
- The wood is tougher than hickory, which is tougher than hard maple, which is tougher than oak.
- A very low rate of expansion and contraction
- Hardwood flooring
- The highest tensile beam strength of any American tree
- The wood is beautiful
## Legume
- Nitrogen fixer
- Fixes the same amount of nitrogen per acre as is needed for 200-bushel/acre corn
- Black walnuts inter-planted with locust as “nurse” trees were shown to rapidly increase their growth [[Clark, Paul M., and Robert D. Williams. (1978) Black walnut growth increased when interplanted with nitrogen-fixing shrubs and trees. Proceedings of the Indiana Academy of Science, vol. 88, pp. 88-91.]]
## Bees
![image](https://yakihonne.s3.ap-east-1.amazonaws.com/6389be6491e7b693e9f368ece88fcd145f07c068d2c1bbae4247b9b5ef439d32/files/1736980846612-YAKIHONNES3.jpg)
- The edible flower clusters are also a top food source for honey bees
## Shade Provider
![image](https://yakihonne.s3.ap-east-1.amazonaws.com/6389be6491e7b693e9f368ece88fcd145f07c068d2c1bbae4247b9b5ef439d32/files/1736980932988-YAKIHONNES3.jpg)
- Its light, airy overstory provides dappled shade
- Planted on the west side of a garden it provides relief during the hottest part of the day
- (nitrogen provider)
- Planted on the west side of a house, its quick growth soon shades that side from the sun
## Wind-break
![image](https://yakihonne.s3.ap-east-1.amazonaws.com/6389be6491e7b693e9f368ece88fcd145f07c068d2c1bbae4247b9b5ef439d32/files/1736980969926-YAKIHONNES3.jpg)
- Fast growth plus it's feathery foliage reduces wind for animals, crops, and shelters
## Fodder
- Over 20% crude protein
- 4.1 kcal/g of energy
- Baertsche, S.R, M.T. Yokoyama, and J.W. Hanover (1986) Short rotation, hardwood tree biomass as potential ruminant feed-chemical composition, nylon bag ruminal degradation and ensilement of selected species. J. Animal Sci. 63 2028-2043
-
@ 1bda7e1f:bb97c4d9
2025-01-02 05:19:08
### Tldr
- Nostr is an open and interoperable protocol
- You can integrate it with workflow automation tools to augment your experience
- n8n is a great low/no-code workflow automation tool which you can host yourself
- Nostrobots allows you to integrate Nostr into n8n
- In this blog I create some workflow automations for Nostr
- A simple form to delegate posting notes
- Push notifications for mentions on multiple accounts
- Push notifications for your favourite accounts when they post a note
- All workflows are provided as open source with MIT license for you to use
### Inter-op All The Things
Nostr is a new open social protocol for the internet. This open nature exciting because of the opportunities for interoperability with other technologies. In [Using NFC Cards with Nostr]() I explored the `nostr:` URI to launch Nostr clients from a card tap.
The interoperability of Nostr doesn't stop there. The internet has many super-powers, and Nostr is open to all of them. Simply, there's no one to stop it. There is no one in charge, there are no permissioned APIs, and there are no risks of being de-platformed. If you can imagine technologies that would work well with Nostr, then any and all of them can ride on or alongside Nostr rails.
My mental model for why this is special is Google Wave ~2010. Google Wave was to be the next big platform. Lars was running it and had a big track record from Maps. I was excited for it. Then, Google pulled the plug. And, immediately all the time and capital invested in understanding and building on the platform was wasted.
This cannot happen to Nostr, as there is no one to pull the plug, and maybe even no plug to pull.
So long as users demand Nostr, Nostr will exist, and that is a pretty strong guarantee. It makes it worthwhile to invest in bringing Nostr into our other applications.
All we need are simple ways to plug things together.
### Nostr and Workflow Automation
Workflow automation is about helping people to streamline their work. As a user, the most common way I achieve this is by connecting disparate systems together. By setting up one system to trigger another or to move data between systems, I can solve for many different problems and become way more effective.
#### n8n for workflow automation
Many workflow automation tools exist. My favourite is [n8n](https://n8n.io/). n8n is a low/no-code workflow automation platform which allows you to build all kinds of workflows. You can use it for free, you can self-host it, it has a user-friendly UI and useful API. Vs Zapier it can be far more elaborate. Vs Make.com I find it to be more intuitive in how it abstracts away the right parts of the code, but still allows you to code when you need to.
Most importantly you can plug anything into n8n: You have built-in nodes for specific applications. HTTP nodes for any other API-based service. And community nodes built by individual community members for any other purpose you can imagine.
#### Eating my own dogfood
It's very clear to me that there is a big design space here just demanding to be explored. If you could integrate Nostr with anything, what would you do?
In my view the best way for anyone to start anything is by solving their own problem first (aka "scratching your own itch" and "eating your own dogfood"). As I get deeper into Nostr I find myself controlling multiple Npubs – to date I have a personal Npub, a brand Npub for a community I am helping, an AI assistant Npub, and various testing Npubs. I need ways to delegate access to those Npubs without handing over the keys, ways to know if they're mentioned, and ways to know if they're posting.
I can build workflows with n8n to solve these issues for myself to start with, and keep expanding from there as new needs come up.
### Running n8n with Nostrobots
I am mostly non-technical with a very helpful AI. To set up n8n to work with Nostr and operate these workflows should be possible for anyone with basic technology skills.
- I have a cheap VPS which currently runs my [HAVEN Nostr Relay](https://rodbishop.npub.pro/post/8ca68889/) and [Albyhub Lightning Node](https://rodbishop.npub.pro/post/setting-up-payments-on-nostr-7o6ls7/) in Docker containers,
- My objective was to set up n8n to run alongside these in a separate Docker container on the same server, install the required nodes, and then build and host my workflows.
#### Installing n8n
Self-hosting n8n could not be easier. I followed n8n's [Docker-Compose installation docs](https://docs.n8n.io/hosting/installation/server-setups/docker-compose/)–
- Install Docker and Docker-Compose if you haven't already,
- Create your ``docker-compose.yml`` and `.env` files from the docs,
- Create your data folder `sudo docker volume create n8n_data`,
- Start your container with `sudo docker compose up -d`,
- Your n8n instance should be online at port `5678`.
n8n is free to self-host but does require a license. Enter your credentials into n8n to get your free license key. You should now have access to the Workflow dashboard and can create and host any kind of workflows from there.
#### Installing Nostrobots
To integrate n8n nicely with Nostr, I used the [Nostrobots](https://github.com/ocknamo/n8n-nodes-nostrobots?tab=readme-ov-file) community node by [Ocknamo](nostr:npub1y6aja0kkc4fdvuxgqjcdv4fx0v7xv2epuqnddey2eyaxquznp9vq0tp75l).
In n8n parlance a "node" enables certain functionality as a step in a workflow e.g. a "set" node sets a variable, a "send email" node sends an email. n8n comes with all kinds of "official" nodes installed by default, and Nostr is not amongst them. However, n8n also comes with a framework for community members to create their own "community" nodes, which is where Nostrobots comes in.
You can only use a community node in a self-hosted n8n instance (which is what you have if you are running in Docker on your own server, but this limitation does prevent you from using n8n's own hosted alternative).
To install a community node, [see n8n community node docs](https://docs.n8n.io/integrations/community-nodes/installation/gui-install/). From your workflow dashboard–
- Click the "..." in the bottom left corner beside your username, and click "settings",
- Cilck "community nodes" left sidebar,
- Click "Install",
- Enter the "npm Package Name" which is `n8n-nodes-nostrobots`,
- Accept the risks and click "Install",
- Nostrobots is now added to your n8n instance.
#### Using Nostrobots
Nostrobots gives you nodes to help you build Nostr-integrated workflows–
- **Nostr Write** – for posting Notes to the Nostr network,
- **Nostr Read** – for reading Notes from the Nostr network, and
- **Nostr Utils** – for performing certain conversions you may need (e.g. from bech32 to hex).
Nostrobots has [good documentation](https://github.com/ocknamo/n8n-nodes-nostrobots?tab=readme-ov-file) on each node which focuses on simple use cases.
Each node has a "convenience mode" by default. For example, the "Read" Node by default will fetch Kind 1 notes by a simple filter, in Nostrobots parlance a "Strategy". For example, with Strategy set to "Mention" the node will accept a pubkey and fetch all Kind 1 notes that Mention the pubkey within a time period. This is very good for quick use.
What wasn't clear to me initially (until Ocknamo helped me out) is that advanced use cases are also possible.
Each node also has an advanced mode. For example, the "Read" Node can have "Strategy" set to "RawFilter(advanced)". Now the node will accept json (anything you like that complies with [NIP-01](https://github.com/nostr-protocol/nips/blob/master/01.md)). You can use this to query Notes (Kind 1) as above, and also Profiles (Kind 0), Follow Lists (Kind 3), Reactions (Kind 7), Zaps (Kind 9734/9735), and anything else you can think of.
#### Creating and adding workflows
With n8n and Nostrobots installed, you can now create or add any kind of Nostr Workflow Automation.
- Click "Add workflow" to go to the workflow builder screen,
- If you would like to build your own workflow, you can start with adding any node. Click "+" and see what is available. Type "Nostr" to explore the Nostrobots nodes you have added,
- If you would like to add workflows that someone else has built, click "..." in the top right. Then click "import from URL" and paste in the URL of any workflow you would like to use (including the ones I share later in this article).
### Nostr Workflow Automations
It's time to build some things!
#### A simple form to post a note to Nostr
I started very simply. I needed to delegate the ability to post to Npubs that I own in order that a (future) team can test things for me. I don't want to worry about managing or training those people on how to use keys, and I want to revoke access easily.
I needed a basic form with credentials that posted a Note.
For this I can use a very simple workflow–
- **A n8n Form node** – Creates a form for users to enter the note they wish to post. Allows for the form to be protected by a username and password. This node is the workflow "trigger" so that the workflow runs each time the form is submitted.
- **A Set node** – Allows me to set some variables, in this case I set the relays that I intend to use. I typically add a Set node immediately following the trigger node, and put all the variables I need in this. It helps to make the workflows easier to update and maintain.
- **A Nostr Write node** (from Nostrobots) – Writes a Kind-1 note to the Nostr network. It accepts Nostr credentials, the output of the Form node, and the relays from the Set node, and posts the Note to those relays.
Once the workflow is built, you can test it with the testing form URL, and set it to "Active" to use the production form URL. That's it. You can now give posting access to anyone for any Npub. To revoke access, simply change the credentials or set to workflow to "Inactive".
It may also be the world's simplest Nostr client.
You can find the [Nostr Form to Post a Note workflow here](https://github.com/r0d8lsh0p/nostr-n8n/blob/main/Nostr_Form_to_Post_a_Note.json).
#### Push notifications on mentions and new notes
One of the things Nostr is not very good at is push notifications. Furthermore I have some unique itches to scratch. I want–
- **To make sure I never miss a note addressed to any of my Npubs** – For this I want a push notification any time any Nostr user mentions any of my Npubs,
- **To make sure I always see all notes from key accounts** – For this I need a push notification any time any of my Npubs post any Notes to the network,
- **To get these notifications on all of my devices** – Not just my phone where my Nostr regular client lives, but also on each of my laptops to suit wherever I am working that day.
I needed to build a Nostr push notifications solution.
To build this workflow I had to string a few ideas together–
- **Triggering the node on a schedule** – Nostrobots does not include a trigger node. As every workflow starts with a trigger we needed a different method. I elected to run the workflow on a schedule of every 10-minutes. Frequent enough to see Notes while they are hot, but infrequent enough to not burden public relays or get rate-limited,
- **Storing a list of Npubs in a Nostr list** – I needed a way to store the list of Npubs that trigger my notifications. I initially used an array defined in the workflow, this worked fine. Then I decided to try Nostr lists ([NIP-51, kind 30000](https://github.com/nostr-protocol/nips/blob/master/51.md)). By defining my list of Npubs as a list published to Nostr I can control my list from within a Nostr client (e.g. [Listr.lol](https://listr.lol/npub1r0d8u8mnj6769500nypnm28a9hpk9qg8jr0ehe30tygr3wuhcnvs4rfsft) or [Nostrudel.ninja](https://nostrudel.ninja/#/lists)). Not only does this "just work", but because it's based on Nostr lists automagically Amethyst client allows me to browse that list as a Feed, and everyone I add gets notified in their Mentions,
- **Using specific relays** – I needed to query the right relays, including my own HAVEN relay inbox for notes addressed to me, and wss://purplepag.es for Nostr profile metadata,
- **Querying Nostr events** (with Nostrobots) – I needed to make use of many different Nostr queries and use quite a wide range of what Nostrobots can do–
- I read the EventID of my Kind 30000 list, to return the desired pubkeys,
- For notifications on mentions, I read all Kind 1 notes that mention that pubkey,
- For notifications on new notes, I read all Kind 1 notes published by that pubkey,
- Where there are notes, I read the Kind 0 profile metadata event of that pubkey to get the displayName of the relevant Npub,
- I transform the EventID into a Nevent to help clients find it.
- **Using the Nostr URI** – As I did with my NFC card article, I created a link with the `nostr:` URI prefix so that my phone's native client opens the link by default,
- **Push notifications solution** – I needed a push notifications solution. I found many with n8n integrations and chose to go with [Pushover](https://pushover.net/) which supports all my devices, has a free trial, and is unfairly cheap with a $5-per-device perpetual license.
Once the workflow was built, lists published, and Pushover installed on my phone, I was fully set up with push notifications on Nostr. I have used these workflows for several weeks now and made various tweaks as I went. They are feeling robust and I'd welcome you to give them a go.
You can find the [Nostr Push Notification If Mentioned here](https://github.com/r0d8lsh0p/nostr-n8n/blob/main/Nostr_Push_Notify_If_Mentioned.json) and [If Posts a Note here](https://github.com/r0d8lsh0p/nostr-n8n/blob/main/Nostr_Push_Notify_If_Post_a_Note.json).
In speaking with other Nostr users while I was building this, there are all kind of other needs for push notifications too – like on replies to a certain bookmarked note, or when a followed Npub starts streaming on zap.stream. These are all possible.
#### Use my workflows
I have open sourced all my workflows at my [Github](https://github.com/r0d8lsh0p/nostr-n8n) with MIT license and tried to write complete docs, so that you can import them into your n8n and configure them for your own use.
To import any of my workflows–
- Click on the workflow of your choice, e.g. "[Nostr_Push_Notify_If_Mentioned.json](https://github.com/r0d8lsh0p/nostr-n8n/blob/main/Nostr_Push_Notify_If_Mentioned.json "Nostr_Push_Notify_If_Mentioned.json")",
- Click on the "raw" button to view the raw JSON, ex any Github page layout,
- Copy that URL,
- Enter that URL in the "import from URL" dialog [mentioned above](#creating-and-adding-workflows).
To configure them–
- Prerequisites, credentials, and variables are all stated,
- In general any variables required are entered into a Set Node that follows the trigger node,
- Pushover has some extra setup but is very straightforward and documented in the workflow.
### What next?
Over my first four blogs I explored creating a good Nostr setup with [Vanity Npub](https://rodbishop.npub.pro/post/mining-your-vanity-pubkey-4iupbf/), [Lightning Payments](https://rodbishop.npub.pro/post/setting-up-payments-on-nostr-7o6ls7/), [Nostr Addresses at Your Domain](https://rodbishop.npub.pro/post/ee8a46bc/), and [Personal Nostr Relay](https://rodbishop.npub.pro/post/8ca68889/).
Then in my latest two blogs I explored different types of interoperability [with NFC cards](https://rodbishop.npub.pro/post/edde8387/) and now n8n Workflow Automation.
Thinking ahead n8n can power any kind of interoperability between Nostr and any other legacy technology solution. On my mind as I write this:
- Further enhancements to posting and delegating solutions and forms (enhanced UI or different note kinds),
- Automated or scheduled posting (such as auto-liking everything [Lyn Alden](nostr:npub1a2cww4kn9wqte4ry70vyfwqyqvpswksna27rtxd8vty6c74era8sdcw83a) posts),
- Further enhancements to push notifications, on new and different types of events (such as notifying me when I get a new follower, on replies to certain posts, or when a user starts streaming),
- All kinds of bridges, such as bridging notes to and from Telegram, Slack, or Campfire. Or bridging RSS or other event feeds to Nostr,
- All kinds of other automation (such as [BlackCoffee](nostr:npub1dqepr0g4t3ahvnjtnxazvws4rkqjpxl854n29wcew8wph0fmw90qlsmmgt) [controlling a coffee machine](https://primal.net/e/note16fzhh5yfc3u4kufx0mck63tsfperdrlpp96am2lmq066cnuqutds8retc3)),
- All kinds of AI Assistants and Agents,
In fact I have already released an open source workflow for an [AI Assistant](https://primal.net/p/npub1ahjpx53ewavp23g5zj9jgyfrpr8djmgjzg5mpe4xd0z69dqvq0kq2lf353), and will share more about that in my next blog.
Please be sure to let me know if you think there's another Nostr topic you'd like to see me tackle.
GM Nostr.
-
@ 4ba8e86d:89d32de4
2024-11-07 13:56:21
Tutorial feito por Grom mestre⚡poste original abaixo:
http://xh6liiypqffzwnu5734ucwps37tn2g6npthvugz3gdoqpikujju525yd.onion/240277/tutorial-criando-e-acessando-sua-conta-de-email-pela-i2p?show=240277#q240277
Bom dia/tarde/noite a todos os camaradas.
Seguindo a nossa série de tutoriais referentes a tecnologias essenciais para a segurança e o anonimato dos usuários, sendo as primeiras a openPGP e a I2P, lhes apresento mais uma opção para expandir os seus conhecimentos da DW.
Muitos devem conhecer os serviços de mail na onion como DNMX e mail2tor, mas e que tal um serviço de email pela I2P. Nesse tutorial eu vou mostrar a vocês como criar a sua primeira conta no hq.postman.i2p e a acessar essa conta.
É importante que vocês tenham lido a minha primeira série de tutoriais a respeito de como instalar, configurar e navegar pela I2P nostr:nevent1qqsyjcz2w0e6d6dcdeprhuuarw4aqkw730y542dzlwxwssneq3mwpaspz4mhxue69uhhyetvv9ujuerpd46hxtnfduhsygzt4r5x6tvh39kujvmu8egqdyvf84e3w4e0mq0ckswamfwcn5eduspsgqqqqqqsyp5vcq Esse tutorial é um pré-requisito para o seguinte e portanto recomendo que leia-os antes de prosseguir com o seguinte tutorial. O tutorial de Kleopatra nostr:nevent1qqs8h7vsn5j6qh35949sa60dms4fneussmv9jd76n24lsmtz24k0xlqzyp9636rd9ktcjmwfxd7ru5qxjxyn6uch2uhas8utg8wa5hvf6vk7gqcyqqqqqqgecq8f7 é complementar dado que é extremamente recomendado assinar e criptografar as mensagens que seguem por emails pela DW.
Sem mais delongas, vamos ao tutorial de fato.
## 1. Criando uma conta de email no hq.postman
Relembrando: Esse tutorial considera que você já tenha acesso à I2P.
Entre no seu navegador e acesse o endereço hq.postman.i2p. O roteador provavelmente já contém esse endereço no seu addressbook e não haverá a necessidade de inserir o endereço b32 completo.
Após entrar no site vá para a página '1 - Creating a mailbox'
https://image.nostr.build/d850379fe315d2abab71430949b06d3fa49366d91df4c9b00a4a8367d53fcca3.jpg
Nessa página, insira as credenciais de sua preferências nos campos do formulário abaixo. Lembre-se que o seu endereço de email aceita apenas letras e números. Clique em 'Proceed' depois que preencher todos os campos.
https://image.nostr.build/670dfda7264db393e48391f217e60a2eb87d85c2729360c8ef6fe0cf52508ab4.jpg
Uma página vai aparecer pedindo para confirmar as credenciais da sua nova conta. Se tudo estiver certo apenas clique em 'Confirm and Create Mailbox'. Se tudo ocorrer como conforme haverá uma confirmação de que a sua nova conta foi criada com sucesso. Após isso aguarde por volta de 5 minutos antes de tentar acessá-la, para que haja tempo suficiente para o servidor atualizar o banco de dados.
https://image.nostr.build/ec58fb826bffa60791fedfd9c89a25d592ac3d11645b270c936c60a7c59c067f.jpg
https://image.nostr.build/a2b7710d1e3cbb36431acb9055fd62937986b4da4b1a1bbb06d3f3cb1f544fd3.jpg
Pronto! Sua nova conta de email na I2P foi criada. Agora vamos para a próxima etapa: como acessar a sua conta via um cliente de email.
## 2. Configurando os túneis cliente de SMTP e POP3
O hq.postman não possui um cliente web que nos permite acessar a nossa conta pelo navegador. Para isso precisamos usar um cliente como Thunderbird e configurar os túneis cliente no I2Pd que serão necessários para o Thunderbird se comunicar com o servidor pela I2P.
Caso não tenha instalado o Thunderbird ainda, faça-o agora antes de prosseguir.
Vamos configurar os túneis cliente do servidor de email no nosso roteador. Para isso abra um terminal ou o seu gestor de arquivos e vá para a pasta de configuração de túneis do I2P. Em Linux esse diretório se localiza em /etc/i2pd/tunnels.d. Em Windows, essa pasta se localiza em C:\users\user\APPDATA\i2pd.
Na pasta tunnels.d crie dois arquivos: smtp.postman.conf e pop-postman.conf. Lembre-se que em Linux você precisa de permissões de root para escrever na pasta de configuração. Use o comando sudoedit <nome_do_arquivo> para isso.
Edite-os conforme as imagens a seguir:
Arquivo pop-postman.conf
https://image.nostr.build/7e03505c8bc3b632ca5db1f8eaefc6cecb4743cd2096d211dd90bbdc16fe2593.jpg
Arquivo smtp-postman.conf
https://image.nostr.build/2d06c021841dedd6000c9fc2a641ed519b3be3c6125000b188842cd0a5af3d16.jpg
Salve os arquivos e reinicie o serviço do I2Pd. Em Linux isso é feito pelo comando:
```
sudo systemctl restart i2pd
```
Entre no Webconsole do I2Pd pelo navegador (localhost:7070) e na seção I2P Tunnels, verifique se os túneis pop-postman e smtp-postman foram criados, caso contrário verifique se há algum erro nos arquivos e reinicie o serviço.
Com os túneis cliente criados, vamos agora configurar o Thunderbird
## 3. Configurando o Thunderbird para acessar a nossa conta
Abra o Thunderbird e clique em criar uma nova conta de email. Se você não tiver nenhum conta previamente presente nele você vai ser diretamente recebido pela janela de criação de conta a seguir.
https://image.nostr.build/e9509d7bd30623716ef9adcad76c1d465f5bc3d5840e0c35fe4faa85740f41b4.jpg
https://image.nostr.build/688b59b8352a17389902ec1e99d7484e310d7d287491b34f562b8cdd9dbe8a99.jpg
Coloque as suas credenciais, mas não clique ainda em Continuar. Clique antes em Configure Manually, já que precisamos configurar manualmente os servidores de SMTP e POP3 para, respectivamente, enviar e receber mensagens.
Preencha os campos como na imagem a seguir. Detalhe: Não coloque o seu endereço completo com o @mail.i2p, apenas o nome da sua conta.
https://image.nostr.build/4610b0315c0a3b741965d3d7c1e4aff6425a167297e323ba8490f4325f40cdcc.jpg
Clique em Re-test para verificar a integridade da conexão. Se tudo estiver certo uma mensagem irá aparecer avisando que as configurações do servidores estão corretas. Clique em Done assim que estiver pronto para prosseguir.
https://image.nostr.build/8a47bb292f94b0d9d474d4d4a134f8d73afb84ecf1d4c0a7eb6366d46bf3973a.jpg
A seguinte mensagem vai aparecer alertando que não estamos usando criptografia no envio das credenciais. Não há problema nenhum aqui, pois a I2P está garantindo toda a proteção e anonimato dos nossos dados, o que dispensa a necessidade de uso de TLS ou qualquer tecnologia similar nas camadas acima. Marque a opção 'I Understand the risks' e clique em 'Continue'
https://image.nostr.build/9c1bf585248773297d2cb1d9705c1be3bd815e2be85d4342227f1db2f13a9cc6.jpg
E por fim, se tudo ocorreu como devido sua conta será criada com sucesso e você agora será capaz de enviar e receber emails pela I2P usando essa conta.
https://image.nostr.build/8ba7f2c160453c9bfa172fa9a30b642a7ee9ae3eeb9b78b4dc24ce25aa2c7ecc.jpg
## 4. Observações e considerações finais
Como informado pelo próprio site do hq.postman, o domínio @mail.i2p serve apenas para emails enviados dentro da I2P. Emails enviados pela surface devem usar o domínio @i2pmai.org. É imprescindível que você saiba usar o PGP para assinar e criptografar as suas mensagens, dado que provavelmente as mensagens não são armazenadas de forma criptografada enquanto elas estão armazenadas no servidor. Como o protocolo POP3 delete as mensagens no imediato momento em que você as recebe, não há necessidade de fazer qualquer limpeza na sua conta de forma manual.
Por fim, espero que esse tutorial tenha sido útil para vocês. Que seu conhecimento tenha expandido ainda mais com as informações trazidas aqui. Até a próxima.
-
@ 266815e0:6cd408a5
2024-04-24 23:02:21
> NOTE: this is just a quick technical guide. sorry for the lack of details
## Install NodeJS
Download it from the official website
https://nodejs.org/en/download
Or use nvm
https://github.com/nvm-sh/nvm?tab=readme-ov-file#install--update-script
```bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
nvm install 20
```
## Clone example config.yml
```bash
wget https://raw.githubusercontent.com/hzrd149/blossom-server/master/config.example.yml -O config.yml
```
## Modify config.yml
```bash
nano config.yml
# or if your that type of person
vim config.yml
```
## Run blossom-server
```bash
npx blossom-server-ts
# or install it locally and run using npm
npm install blossom-server-ts
./node_modules/.bin/blossom-server-ts
```
Now you can open http://localhost:3000 and see your blossom server
And if you set the `dashboard.enabled` option in the `config.yml` you can open http://localhost:3000/admin to see the admin dashboard
-
@ 3bf0c63f:aefa459d
2024-03-19 14:01:01
# Nostr is not decentralized nor censorship-resistant
Peter Todd has been [saying this](nostr:nevent1qqsq5zzu9ezhgq6es36jgg94wxsa2xh55p4tfa56yklsvjemsw7vj3cpp4mhxue69uhkummn9ekx7mqpr4mhxue69uhkummnw3ez6ur4vgh8wetvd3hhyer9wghxuet5qy8hwumn8ghj7mn0wd68ytnddaksz9rhwden5te0dehhxarj9ehhsarj9ejx2aspzfmhxue69uhk7enxvd5xz6tw9ec82cspz3mhxue69uhhyetvv9ujuerpd46hxtnfduq3vamnwvaz7tmjv4kxz7fwdehhxarj9e3xzmnyqy28wumn8ghj7un9d3shjtnwdaehgu3wvfnsz9nhwden5te0wfjkccte9ec8y6tdv9kzumn9wspzpn92tr3hexwgt0z7w4qz3fcch4ryshja8jeng453aj4c83646jxvxkyvs4) for a long time and all the time I've been thinking he is misunderstanding everything, but I guess a more charitable interpretation is that he is right.
Nostr _today_ is indeed centralized.
Yesterday I published two harmless notes with the exact same content at the same time. In two minutes the notes had a noticeable difference in responses:
![](https://blob.satellite.earth/53b3eec9ffaada20b7c27dee4fa7a935adedcc337b9332b619c782b030eb5226)
The top one was published to `wss://nostr.wine`, `wss://nos.lol`, `wss://pyramid.fiatjaf.com`. The second was published to the relay where I generally publish all my notes to, `wss://pyramid.fiatjaf.com`, and that is announced on my [NIP-05 file](https://fiatjaf.com/.well-known/nostr.json) and on my [NIP-65](https://nips.nostr.com/65) relay list.
A few minutes later I published that screenshot again in two identical notes to the same sets of relays, asking if people understood the implications. The difference in quantity of responses can still be seen today:
![](https://blob.satellite.earth/df993c3fb91eaeff461186248c54f39c2eca3505b68dac3dc9757c77e9373379)
These results are skewed now by the fact that the two notes got rebroadcasted to multiple relays after some time, but the fundamental point remains.
What happened was that a huge lot more of people saw the first note compared to the second, and if Nostr was really censorship-resistant that shouldn't have happened at all.
Some people implied in the comments, with an air of obviousness, that publishing the note to "more relays" should have predictably resulted in more replies, which, again, shouldn't be the case if Nostr is really censorship-resistant.
What happens is that most people who engaged with the note are _following me_, in the sense that they have instructed their clients to fetch my notes on their behalf and present them in the UI, and clients are failing to do that despite me making it clear in multiple ways that my notes are to be found on `wss://pyramid.fiatjaf.com`.
If we were talking not about me, but about some public figure that was being censored by the State and got banned (or shadowbanned) by the 3 biggest public relays, the sad reality would be that the person would immediately get his reach reduced to ~10% of what they had before. This is not at all unlike what happened to dozens of personalities that were banned from the corporate social media platforms and then moved to other platforms -- how many of their original followers switched to these other platforms? Probably some small percentage close to 10%. In that sense Nostr today is similar to what we had before.
Peter Todd is right that if the way Nostr works is that you just subscribe to a small set of relays and expect to get everything from them then it tends to get very centralized very fast, and this is the reality today.
Peter Todd is wrong that Nostr is _inherently_ centralized or that it needs a _protocol change_ to become what it has always purported to be. He is in fact wrong today, because what is written above is not valid for all clients of today, and if we [drive in the right direction](bc63c348b) we can successfully make Peter Todd be more and more wrong as time passes, instead of the contrary.
---
See also:
- [Censorship-resistant relay discovery in Nostr](nostr:naddr1qqykycekxd3nxdpcvgq3zamnwvaz7tmxd9shg6npvchxxmmdqgsrhuxx8l9ex335q7he0f09aej04zpazpl0ne2cgukyawd24mayt8grqsqqqa2803ksy8)
- [A vision for content discovery and relay usage for basic social-networking in Nostr](nostr:naddr1qqyrxe33xqmxgve3qyghwumn8ghj7enfv96x5ctx9e3k7mgzyqalp33lewf5vdq847t6te0wvnags0gs0mu72kz8938tn24wlfze6qcyqqq823cywwjvq)