Making The Spam Bots Work

--

Spamming is still a major problem on email and bulletin boards. Why? Because it is free to post things and does not require a good deal of work. If it was more costly, it would likely result in much less spam. With Bitcoin, we make it difficult for the miners by asking them to find a nonce value for a block so that the hash of the block has a predefined number of zeroes. This means that each miner must commit a given amount of work in order to become part of the mining process. It will then be too costly for an adversary to try and take over the mining process, as they would have to invest in a large amount of hardware and pay for the associated energy costs. In the following, we see that the hash value of the block has a given number of zeros for the hash of the block:

With Nostr (Notes and Other Stuff Transmitted by Relays). we can use NIP-13 to generate a Proof of Work for notes and where we have a preceeding number of zero values for rthe ID. This provides a way of showing computation work. Overall it is used to deter spamming bots — as each of them would have to create considerable amount of work to produce spam messages. The difficulty is defined by the number of leading zero bits in the event ID. For example, if we have an ID of 00002b12c714aa9a93b5fafe4a7d1be5d2bf452481ee7229d3ae9c8e6777e2bb then we have four hex zero values, and thus have 16 zeros. This defines a difficulty of 16.

We can create the PoW with [here]:

`<	ev := nostr.Event{	PubKey:    pk,	CreatedAt: nostr.Now(),	Kind:      nostr.KindTextNote,	Tags:      nil,	Content:   msg,	}_,_=nip13.Generate(&ev,bits,1000000000)`

This will create an ID with a given number of bits and with a time-out of 1,000,000,000 nanoseconds. This ID can then be checked by the receiver to have those numbers of zero bits. Otherwise, it will be rejected.

The following is some sample code [here]:

`package mainimport (    "fmt"     "os" "strconv"    "github.com/nbd-wtf/go-nostr"    "github.com/nbd-wtf/go-nostr/nip19"    "github.com/nbd-wtf/go-nostr/nip13")func main() { msg:="Hello world!" bits:=4 argCount := len(os.Args[1:])        if (argCount>0) {msg= string(os.Args[1])}        if (argCount>1) {bits,_= strconv.Atoi(os.Args[2])}    sk := nostr.GeneratePrivateKey()    pk, _ := nostr.GetPublicKey(sk)    nostr_priv, _ := nip19.EncodePrivateKey(sk)    nostr_pub, _ := nip19.EncodePublicKey(pk)    fmt.Printf("Private key %v\n",sk)    fmt.Printf("Public key: %v\n", pk)    fmt.Printf("Private Nosstr encoded: %v\n",nostr_priv)    fmt.Printf("Public Nosstr encoded: %v\n",nostr_pub)    fmt.Printf("Message: %s\n",msg)    fmt.Printf("Zero bits: %d\n",bits) ev := nostr.Event{ PubKey:    pk, CreatedAt: nostr.Now(), Kind:      nostr.KindTextNote, Tags:      nil, Content:   msg, }// func Generate(event *nostr.Event, targetDifficulty int, timeout time.Duration)  _,_=nip13.Generate(&ev,bits,1000000000)    ev.Sign(sk) fmt.Printf("\nEvent ID: %s\n",ev.ID) fmt.Printf("Event Tags: %v\n",ev.Tags) fmt.Printf("Event Content: %v\n",ev.Content) fmt.Printf("Event Sig: %v\n",ev.Sig) fmt.Printf("Event Kind: %v\n",ev.Kind) fmt.Printf("Event CreatedAt: %v\n",ev.CreatedAt) fmt.Printf("Event Pubkey: %v\n",ev.PubKey)}`

And a sample run with eight bits of zeros in the ID [here]:

`Private key 368aaef73fb8d6d72e81d7550b4df265a551785898db7e42cb48d16d00512992Public key: 04d0da5cd03eca7d0bcc85a93c4b0f629f6387c124fca0fe88ade0b99fe737dfPrivate Nosstr encoded: nsec1x692aaelhrtdwt5p6a2skn0jvkj4z7zcnrdhusktfrgk6qz39xfqgcasyvPublic Nosstr encoded: npub1qngd5hxs8m986z7vsk5ncjc0v20k8p7pyn72pl5g4hstn8l8xl0sgghnkkMessage: Testing 123Zero bits: 8Event ID: 008e0a0ef600ea4483ed1c0fec98eb23e3762d95aab516d7f6a3c2f88291c211Event Tags: [[nonce 108 8]]Event Content: Testing 123Event Sig: 3966744cfe232dea2186ac96cfbc09acc10b6d8703d9bc27d59f1555cd5459ae365af527d5e54c4bda1e335b282691f74652bf5bde9b21d170ebf79a8c355ee1Event Kind: 1Event CreatedAt: 1714987090Event Pubkey: 04d0da5cd03eca7d0bcc85a93c4b0f629f6387c124fca0fe88ade0b99fe737df`

And a sample run with 14 bits of zeros in the ID [here]:

`Private key 892459ced613d12a73045042d41367b32485736477ca75c6d2a169a574a3aeebPublic key: 7836dd4328ccbb71508c2f7b3f9ebd44cbe18179eba51f86f88af08b4fba14a2Private Nosstr encoded: nsec13yj9nnkkz0gj5ucy2ppdgym8kvjg2umywl98t3kj59562a9r4m4syecul5Public Nosstr encoded: npub10qmd6segejahz5yv9aanl84agn97rqteawj3lphc3tcgkna6zj3qsjjlxmMessage: Testing 123Zero bits: 14Event ID: 000248fba3d1039e350956d182aad1e08fa8e260c9bb0f0c884ee97edf4509baEvent Tags: [[nonce 18028 14]]Event Content: Testing 123Event Sig: f8530c9467accaff96686d2d50b23a40f4492e88dd0176543ec42779bbdc66dfbbf83dc9e1558bdc38951545c8b37e51a12d88ec9eb249c994c41a2bb25d726bEvent Kind: 1Event CreatedAt: 1714987022Event Pubkey: 7836dd4328ccbb71508c2f7b3f9ebd44cbe18179eba51f86f88af08b4fba14a2`

--

--

Professor of Cryptography. Serial innovator. Believer in fairness, justice & freedom. Based in Edinburgh. Old World Breaker. New World Creator. Building trust.