InFeeo
Global
All
New
Language

Channels

A conversation with a colleague who believes he bought "2 whole Bitcoins"(reddit.com)
A couple of months ago, a colleague proudly told me that he had purchased "2 whole bitcoins" for $80,000 each. I asked him to show them to me so I could see what he had spent $160,000 on. He opened his wallet application and pointed to the screen, which displayed 2 BTC. When he claimed that those were his bitcoins, I disagreed, explaining that he was merely showing me a record, i.e. one symbol, not two of something. To prove my point, I wrote "2 BTC" on a piece of paper, held it up, and joked that I had just created two bitcoins for free. He laughed and objected, arguing that my paper note wasn't Bitcoin. He explained that Bitcoin only exists when a network of computers running the Bitcoin protocol records that someone has 2 BTC. ​I accepted his premise and suggested we break down the entire Bitcoin system to see what we could find. ​So, you have the network of computers, the software, the protocol, the cryptographic keys, and the blockchain records, including his own "2 BTC." Yet, despite accounting for all of it, nothing that could actually be defined as "two bitcoins" was there. I pointed out to him that his purchase was no different from what I had written on the paper for free. At that point, my colleague shifted the argument to fiat currency. He countered that if I had $1,000 in a banking app, he could similarly write "$1,000" on a piece of paper and have exactly the same thing for free. I rejected his comparison and proposed that we examine the banking system the same way we did with Bitcoin. I explained that while we would find computers, software, protocols, and database records showing my 1,000 USD, we would also find the underlying loan contracts that created those records. We would find real borrowers who are legally required to repay those loans. Therefore, what I have is a thousand units of a claim on the future production of bank debtors. I further explained that those debtors must provide actual goods, services, labor, or assets to earn the dollars needed to settle their debts. If they fail to do so, their property is seized and sold at bank auctions to honor the claim. I noted that when he wrote "$1,000" on a piece of paper, he had only created symbols, not a claim on debtors and their property. Conversely, with his "two bitcoins", I had created the exact same thing he has: symbols. He attempted one last pushback, arguing his bitcoins were valid because they required immense energy consumption and strict mathematical rules, whereas my paper note was completely arbitrary. In response, I told him to hold my pen, dropped to the floor, and hammered out 50 strenuous push-ups. Standing back up, I picked up the pen and wrote a strict rule on the paper stating I would never write a number larger than 2 BTC. I explained that those push-ups were my proof of work and that note was my rule. I pointed out that because my energy expenditure was local and my self-imposed protocol was strictly capped right there, my bitcoins were actually scarcer and more exclusive than his. I concluded that modern snake-oil salesmens had convinced him to give up actual claims equivalent in value to four new cars for something that anyone can create instantly with a few strokes of a pen or taps on a keyboard. My colleague then stated that he didn't want to have this conversation anymore. submitted by /u/BinaryLyric [link] [Kommentare]
2026 is on track to be the worst year for crypto hacks ever. AI is a big reason why(reddit.com)
Q2 2026 just set a record: 83 separate crypto hacks, the most ever in a single quarter. over $750 million stolen. april alone was $606 million across just 12 incidents. and we're barely halfway through the year. but the scary part isn't the numbers. it's how the attacks are happening. multiple security firms (TRM Labs, CertiK, Chainalysis) are now saying the same thing: attackers, especially North Korean groups, are using AI to find and exploit vulnerabilities faster than protocols can patch them. here's what that actually looks like in practice: AI-powered vulnerability scanning. attackers are running AI agents that scan smart contracts continuously for exploitable bugs. a protocol's security team might audit their code once or twice. an attacker's AI agent runs 24/7 for weeks, spending $10-20k in compute to find a single crack. the economics are wildly asymmetric: a defender's audit has a budget and a deadline. an attacker's scan has neither. deepfake social engineering. the Zerion hack in april used AI-generated social engineering in a long-term campaign to steal from hot wallets. there are now tools being sold that use voice manipulation and deepfakes specifically to bypass KYC checks on exchanges. this isn't theoretical. it's a service you can subscribe to. automated exploit development. tasks that used to take skilled researchers months, like reverse-engineering contract logic and chaining exploits, can now be done in hours with AI assistance. the barrier to entry for crypto hacking has dropped dramatically. target selection. AI is being used to identify the highest-value targets by scanning TVL, contract complexity, and security posture across hundreds of protocols simultaneously. attackers are picking their targets more intelligently, not just opportunistically. the result: more frequent attacks, more sophisticated execution, and a structural advantage for attackers over defenders. one security researcher put it bluntly: "before AI, the number of elite hackers was limited. now almost anyone could operate like an elite hacker for a subscription fee." the uncomfortable question this raises for defi: most protocols are still running the same security playbook from 2022. periodic audits, bug bounties, maybe a monitoring dashboard. that worked when attackers were humans with limited time. it doesn't work when the attacker is an AI agent that never sleeps and costs almost nothing to run. what actually needs to change? is it just "more audits and bigger bug bounties" or does the entire security model for on-chain protocols need to be rethought from the ground up? submitted by /u/ginete_tech [link] [Kommentare]
GPU access in 2026 is still fragmented — is there a better market structure for compute? [P](reddit.com)
Anyone building at the model layer knows the procurement problem hasn't gone away. H100s are still allocated unevenly, spot instances get preempted at the worst times, and pricing across providers is deliberately hard to compare. Most teams end up over-provisioning just to feel safe. The traditional fixes — reserved instances, spot bidding, broker marketplaces like CoreWeave or Vast.ai — all have the same problem: no real price transparency and no way to hedge future compute needs. I came across a project called Inferra that's approaching this differently. Instead of another compute marketplace, they're building a derivatives exchange for GPU compute — perpetual futures for specific chips (H100, H200, A100, MI300X, B200, A5000), oracle-priced and on-chain. The idea being that a proper futures market creates price discovery that doesn't currently exist. Still pre-mainnet so nothing to benchmark yet. Whitepaper is at inferra.trade for anyone curious about the architecture. Genuinely interested in the broader question though: is the GPU access problem fundamentally a supply issue, a pricing transparency issue, or a market structure issue? And would futures markets even help at the scale most research teams operate at? submitted by /u/amu4biz [link] [Kommentare]
Tagged data in Haskell (SICP 2.4.2)(xkqr.org)
I have a copy of sicp, or as it is also known, The Wizard Book.11 Structure and Interpretation of Computer Programs; Abelson and Sussman; mit Press; 1996. This book is widely praised, but I can’t take the time to work my way through all of it. However, sometimes I jump into parts of it that look interesting. Today, we’ll see how to support multiple representations of data through tagging. This article is written in Haskell throughout, but at the start it will look a lot like the Lisp code in sicp. I have intentionally tried to recreate the sicp solution as closely as possible, including dynamic typing and all. See the appendix if you’re curious how it works. Complex numbers in two forms Complex numbers can be stored in their rectangular form, where there’s a real and an imaginary part. They can also be stored in polar form, where there’s a magnitude and an angle. The authors ask us to imagine that two people have been working on a library for mathematics, but ended up choosing different ways to store complex numbers. How can they write their code so that they don’t have to agree on one way to store the data? Abelson and Sussman propose a tagged representation, where the data of the complex numbers are paired with a tag, which indicates to the implementation what representation is being used. They suggest the following functions to attach a tag, as well as inspect tagged data. As a last reminder, this is Haskell code, but written in Lisp style to mimic the solution in sicp as closely as possible. In[1]: -- | Tag a value as having a particular representation. attach_tag tag contents = (cons tag contents) -- | Extract the type tag from a tagged value. type_tag datum = (if_ (is_pair datum) (car datum) (error "Bad tagged datum")) -- | Extract the value from a tagged value. contents datum = (if_ (is_pair datum) (cdr datum) (error "Bad tagged datum")) This code uses cons in the Lisp sense, i.e. it creates a pair of two values, with a left hand side, known as the car of the pair, and a right hand side, known as the cdr of the pair. With these, we can check if a complex number is stored in its rectangular or polar representation by inspecting its tag. In[2]: is_rectangular z = (eq (type_tag z) (quote "rectangular")) is_polar z = (eq (type_tag z) (quote "polar")) To create a complex number in either rectangular or polar form, we create a cons cell with the coordinates, and tag that cell with the appropriate symbol. In[3]: make_rectangular re im = (attach_tag (quote "rectangular") (cons re im)) make_polar r a = (attach_tag (quote "polar") (cons r a)) If we have the rectangular coordinates for a complex number, we can extract the real and imaginary part easily, too. These functions assume we have peeled off the tag, and that the data is in the correct format. In[4]: real_part_rectangular z = (car z) imag_part_rectangular z = (cdr z) Similarly, we can easily extract the polar coordinates from a complex number stored in its polar form. These implementations are the same as the above, because these functions are supposed to be run after we have verified the tag is correct, and the tag has been peeled off. In[5]: magnitude_polar z = (car z) angle_polar z = (cdr z) If we want to extract polar coordinates from a complex number stored in rectangular form, or vice versa, we’ll have to do some trigonometry. In[6]: magnitude_rectangular z = (sqrt_ (add_ (square_ (real_part_rectangular z)) (square_ (imag_part_rectangular z)))) angle_rectangular z = (atan_ (imag_part_rectangular z) (real_part_rectangular z)) real_part_polar z = (mul_ (magnitude_polar z) (cos_ (angle_polar z))) imag_part_polar z = (mul_ (magnitude_polar z) (sin_ (angle_polar z))) These functions also assume a particular representation, with the tag peeled off. But, now that we have all of the above, we can write our first generic functions, i.e. those that can work on either representation. They’ll do this by inspecting the tag and then performing the right operation depending on what representation is indicated by the tag. These generic functions will extract the respective coordinates for complex numbers regardless of their underlying representation, by dispatching on the type tag. In[7]: real_part z = (if_ (is_rectangular z) (real_part_rectangular (contents z)) (if_ (is_polar z) (real_part_polar (contents z)) (error "Unknown type"))) imag_part z = (if_ (is_rectangular z) (imag_part_rectangular (contents z)) (if_ (is_polar z) (imag_part_polar (contents z)) (error "Unknown type"))) magnitude z = (if_ (is_rectangular z) (magnitude_rectangular (contents z)) (if_ (is_polar z) (magnitude_polar (contents z)) (error "Unknown type"))) angle z = (if_ (is_rectangular z) (angle_rectangular (contents z)) (if_ (is_polar z) (angle_polar (contents z)) (error "Unknown type"))) Given these, the two people no longer have to agree on how they should store complex numbers. Each can choose their own representation, and then they can write generic maths functions over complex numbers, like these. In[8]: add_complex za zb = (make_rectangular (add_ (real_part za) (real_part zb)) (add_ (imag_part za) (imag_part zb))) mul_complex za zb = (make_polar (mul_ (magnitude za) (magnitude zb)) (add_ (angle za) (angle zb))) These functions are written to exploit that addition of complex numbers is easier in rectangular form, but multiplication is easier in polar form. It doesn’t matter how za and zb are stored, because we get the appropriate coordinates out of them either way. This is the solution in sicp, and we did it in Haskell. But now I got curious if we could leverage the strengths of Haskell to make the code more clear. Ripping out the dynamic typing Dynamic typing has two main drawbacks: When we make a mistake, the code will blow up at 3 am and some poor sod will have to wake up to restore production. Code can get unnecessarily complicated because we are not giving the compiler a chance to help us out. For these reasons, we’ll try to move away from dynamic typing. The first change we’ll make is switch the cons cells for tagged values into actual, compiler-recognised tuples. In[9]: attach_tag tag contents = (tag, contents) type_tag (tag, _) = tag contents (_, datum) = datum This is not much, but it simplifies the tagging code. To take it one step further, there’s no reason for the tag symbol to be dynamically typed, so we’ll change that to a compiler-recognised string. That requires changes to the tag introspection functions and the constructor functions. In[10]: is_rectangular z = type_tag z == "rectangular" is_polar z = type_tag z == "polar" make_rectangular re im = (attach_tag "rectangular" (cons re im)) make_polar r a = (attach_tag "polar" (cons r a)) Previously, if we accidentally wrote code that tried to extract the type tag from a complex number that is not tagged, that would become one of those midnight problems. With these two last changes, that mistake would instead be a compiler error. Much better. For even greater impact, we’ll change the complex value cons cell into a compiler-recognised tuple. This requires changes to the construction of complex numbers, and extraction of coordinates from complex numbers. In[11]: make_rectangular re im = (attach_tag "rectangular" (re, im)) real_part_rectangular (re, _) = re imag_part_rectangular (_, im) = im magnitude_rectangular (re, im) = (sqrt_ (add_ (square_ re) (square_ im))) angle_rectangular (re, im) = (atan_ im re) make_polar r a = (attach_tag "polar" (r, a)) magnitude_polar (r, _) = r angle_polar (_, a) = a real_part_polar (r, a) = (mul_ r (cos_ a)) imag_part_polar (r, a) = (mul_ r (sin_ a)) With this, additional run-time errors disappeared. Previously we called car and cdr on the complex numbers. If we accidentally pass something that’s not a complex number to these functions, it’d blow up in the middle of the night. Now it’s a compiler error. We also benefited from pattern matching to make the code a little easier to read. The next step is to switch the numbers used from dynamic values to compiler-recognised Double values. This removes even more run-time errors, because then it will be impossible to accidentally construct complex numbers out of any values that aren’t numbers. The only changes necessary for this is that any time we do maths, we use the native Haskell operators and functions instead. In[12]: magnitude_rectangular (re, im) = (sqrt (re^2 + im^2)) angle_rectangular (re, im) = atan2 im re real_part_polar (r, a) = r * cos a imag_part_polar (r, a) = r * sin a add_complex za zb = make_rectangular (real_part za + real_part zb) (imag_part za + imag_part zb) mul_complex za zb = make_polar (magnitude za * magnitude zb) (angle za + angle zb) At this point, the code is simpler and more robust, but we’re not done yet. Making the compiler aware of the tagging We’re tagging values with what representation they’re using. Haskell supports this natively, so we don’t have to invent it ourselves. To use the native Haskell tagging, we’ll create a data type with constructors for each type of representation. In[13]: data Complex = Rectangular Double Double | Polar Double Double The tags are now functions that can be called as constructors, and we can use pattern matching to deconstruct them. We proceed to remove all the code we wrote up to this point, and replace it with: In[14]: real_part = \case Rectangular re _ -> re Polar r a -> r * cos a imag_part = \case Rectangular _ im -> im Polar r a -> r * sin a magnitude = \case Rectangular re im -> sqrt (re^2 + im^2) Polar r _ -> r angle = \case Rectangular re im -> atan2 im re Polar _ a -> a add_complex za zb = Rectangular (real_part za + real_part zb) (imag_part za + imag_part zb) mul_complex za zb = Polar (magnitude za * magnitude zb) (angle za + angle zb) How cool is that? We went from 80 lines of Lisp down to 30 lines of Haskell. That’s what happens with high level languages: instead of rolling our own tagging system to handle multiple representations, we use the tagging system built into the language.22 I’m aware modern Lisp-likes, among them Common Lisp, do support tagging natively. It’s still dynamically typed, though! But when we get to this point in the book, Abelson and Sussman reveal that the tagging approach might not be ideal. They propose another alternative: data-directed programming. That’s where we’ll go in the next article. Appendix A: The Lisp library It was a little weird writing dynamically typed Lisp-like code in Haskell, but these were the definitions that made it possible. They’re not general enough to be used as a Lisp replacement, but were tailored for this code in particular. In[15]: import Data.Dynamic -- | Create a symbol. (I know strings are not symbols. Shush!) quote :: String -> Dynamic quote = toDyn -- | Compare two symbols for equality. eq :: Dynamic -> Dynamic -> Bool eq lhs rhs = let sa = fromDyn @String lhs (error "eq: LHS was not a string") sb = fromDyn @String rhs (error "eq: RHS was not a string") in sa == sb -- | Create a numeric value. number :: Double -> Dynamic number = toDyn -- | Make a cons cell from two values. cons :: Dynamic -> Dynamic -> Dynamic cons a b = toDyn (a, b) -- | Extract the first part of a cons cell. car :: Dynamic -> Dynamic car d = case fromDynamic @(Dynamic, Dynamic) d of Just (a, _) -> a _ -> error "car: value was not a pair" -- | Extract the second part of a cons cell. cdr :: Dynamic -> Dynamic cdr d = case fromDynamic @(Dynamic, Dynamic) d of Just (_, b) -> b _ -> error "car: value was not a pair" -- | Check if a value is a dynamic cons cell. is_pair :: Dynamic -> Bool is_pair d = case fromDynamic @(Dynamic, Dynamic) d of Just (_, _) -> True _ -> False -- | A Lisp-like if function without the pesky -- syntax of if/then/else. if_ :: Bool -> a -> a -> a if_ p a b = if p then a else b -- | Apply a numeric function to a dynamic value. apply'1 :: (Double -> Double) -> Dynamic -> Dynamic apply'1 = dynApp . toDyn -- | Apply a numeric binary operator to dynamic values. apply'2 :: (Double -> Double -> Double) -> Dynamic -> Dynamic -> Dynamic apply'2 f = dynApp . (dynApp (toDyn f)) -- | Numeric functions and binary operators we use. add_ = apply'2 (+) mul_ = apply'2 (*) square_ = apply'1 (^2) sqrt_ = apply'1 sqrt cos_ = apply'1 cos sin_ = apply'1 sin atan_ = apply'2 atan2