-
![](/static/nostr-icon-purple-64x64.png)
@ daa41bed:88f54153
2025-02-09 16:50:04
There has been a good bit of discussion on Nostr over the past few days about the merits of zaps as a method of engaging with notes, so after writing a rather lengthy [article on the pros of a strategic Bitcoin reserve](https://geek.npub.pro/post/dxqkgnjplttkvetprg8ox/), I wanted to take some time to chime in on the much more fun topic of digital engagement.
Let's begin by defining a couple of things:
**Nostr** is a decentralized, censorship-resistance protocol whose current biggest use case is social media (think Twitter/X). Instead of relying on company servers, it relies on relays that anyone can spin up and own their own content. Its use cases are much bigger, though, and this article is hosted on my own relay, using my own Nostr relay as an example.
**Zap** is a tip or donation denominated in sats (small units of Bitcoin) sent from one user to another. This is generally done directly over the Lightning Network but is increasingly using Cashu tokens. For the sake of this discussion, how you transmit/receive zaps will be irrelevant, so don't worry if you don't know what [Lightning](https://lightning.network/) or [Cashu](https://cashu.space/) are.
If we look at how users engage with posts and follows/followers on platforms like Twitter, Facebook, etc., it becomes evident that traditional social media thrives on engagement farming. The more outrageous a post, the more likely it will get a reaction. We see a version of this on more visual social platforms like YouTube and TikTok that use carefully crafted thumbnail images to grab the user's attention to click the video. If you'd like to dive deep into the psychology and science behind social media engagement, let me know, and I'd be happy to follow up with another article.
In this user engagement model, a user is given the option to comment or like the original post, or share it among their followers to increase its signal. They receive no value from engaging with the content aside from the dopamine hit of the original experience or having their comment liked back by whatever influencer they provide value to. Ad revenue flows to the content creator. Clout flows to the content creator. Sales revenue from merch and content placement flows to the content creator. We call this a linear economy -- the idea that resources get created, used up, then thrown away. Users create content and farm as much engagement as possible, then the content is forgotten within a few hours as they move on to the next piece of content to be farmed.
What if there were a simple way to give value back to those who engage with your content? By implementing some value-for-value model -- a circular economy. Enter zaps.
![Bye Zaps](https://relay.geektoshi.tech/e5396461029085cb4b735ece3114a0f6a6d54b795d9cf6bdb1b2e4fe35c214b4.png)
Unlike traditional social media platforms, Nostr does not actively use algorithms to determine what content is popular, nor does it push content created for active user engagement to the top of a user's timeline. Yes, there are "trending" and "most zapped" timelines that users can choose to use as their default, but these use relatively straightforward engagement metrics to rank posts for these timelines.
That is not to say that we may not see clients actively seeking to refine timeline algorithms for specific metrics. Still, the beauty of having an open protocol with media that is controlled solely by its users is that users who begin to see their timeline gamed towards specific algorithms can choose to move to another client, and for those who are more tech-savvy, they can opt to run their own relays or create their own clients with personalized algorithms and web of trust scoring systems.
Zaps enable the means to create a new type of social media economy in which creators can earn for creating content and users can earn by actively engaging with it. Like and reposting content is relatively frictionless and costs nothing but a simple button tap. Zaps provide active engagement because they signal to your followers and those of the content creator that this post has genuine value, quite literally in the form of money—sats.
![Zaps are real value](https://relay.geektoshi.tech/a0b0e7a9e361f23e0b3a31292e9931fba401d3b83257e930d6f6e32a6122c01f.png)
I have seen some comments on Nostr claiming that removing likes and reactions is for wealthy people who can afford to send zaps and that the majority of people in the US and around the world do not have the time or money to zap because they have better things to spend their money like feeding their families and paying their bills. While at face value, these may seem like valid arguments, they, unfortunately, represent the brainwashed, defeatist attitude that our current economic (and, by extension, social media) systems aim to instill in all of us to continue extracting value from our lives.
Imagine now, if those people dedicating their own time (time = money) to mine pity points on social media would instead spend that time with genuine value creation by posting content that is meaningful to cultural discussions. Imagine if, instead of complaining that their posts get no zaps and going on a tirade about how much of a victim they are, they would empower themselves to take control of their content and give value back to the world; where would that leave us? How much value could be created on a nascent platform such as Nostr, and how quickly could it overtake other platforms?
Other users argue about user experience and that additional friction (i.e., zaps) leads to lower engagement, as proven by decades of studies on user interaction. While the added friction may turn some users away, does that necessarily provide less value? I argue quite the opposite. You haven't made a few sats from zaps with your content? Can't afford to send some sats to a wallet for zapping? How about using the most excellent available resource and spending 10 seconds of your time to leave a comment? Likes and reactions are valueless transactions. Social media's real value derives from providing monetary compensation and actively engaging in a conversation with posts you find interesting or thought-provoking. Remember when humans thrived on conversation and discussion for entertainment instead of simply being an onlooker of someone else's life?
If you've made it this far, my only request is this: try only zapping and commenting as a method of engagement for two weeks. Sure, you may end up liking a post here and there, but be more mindful of how you interact with the world and break yourself from blind instinct. You'll thank me later.
![OnlyZaps](https://relay.geektoshi.tech/32d39d0b51bad3c422e96b354a51076d38b9a84a8aab971da808131549d89c04.jpeg)
-
![](/static/nostr-icon-purple-64x64.png)
@ 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
-
![](/static/nostr-icon-purple-64x64.png)
@ 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
-
![](/static/nostr-icon-purple-64x64.png)
@ 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
-
![](/static/nostr-icon-purple-64x64.png)
@ 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.
-
![](/static/nostr-icon-purple-64x64.png)
@ 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.
-
![](/static/nostr-icon-purple-64x64.png)
@ 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.
-
![](/static/nostr-icon-purple-64x64.png)
@ 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
```
-
![](/static/nostr-icon-purple-64x64.png)
@ 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... 😏
-
![](/static/nostr-icon-purple-64x64.png)
@ 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**.
-
![](/static/nostr-icon-purple-64x64.png)
@ 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)
-
![](/static/nostr-icon-purple-64x64.png)
@ 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**.
-
![](/static/nostr-icon-purple-64x64.png)
@ 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.
-
![](/static/nostr-icon-purple-64x64.png)
@ 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! 💙
-
![](/static/nostr-icon-purple-64x64.png)
@ 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
-
![](/static/nostr-icon-purple-64x64.png)
@ 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.
###
-
![](/static/nostr-icon-purple-64x64.png)
@ 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>
-
![](/static/nostr-icon-purple-64x64.png)
@ 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.
-
![](/static/nostr-icon-purple-64x64.png)
@ 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.
-
![](/static/nostr-icon-purple-64x64.png)
@ 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