Skip to content

Instantly share code, notes, and snippets.

@melvincarvalho
Last active July 22, 2024 12:15
Show Gist options
  • Save melvincarvalho/15f767fee8ed3e14197b322235e9fe8d to your computer and use it in GitHub Desktop.
Save melvincarvalho/15f767fee8ed3e14197b322235e9fe8d to your computer and use it in GitHub Desktop.

NIP-570: Public On-Chain Zaps and Anti-Zaps

Authors Melvin Carvalho optional draft

Disclaimer: this is an early draft and should be considered v0.0.0, use xxzap in testing, so it is not indexed. Final version should probably used OP_PUSHNUM and OP_PUSHBYTES TBD. That said the spec is ready for experimentation and feedback.

Summary

This proposal outlines a method for implementing simple on-chain zaps between Nostr users using Taproot addresses. The proposal includes specifications for both regular zaps and negative zaps (antizaps).

Motivation

The ability to send zaps (micro-transactions) on-chain between Nostr users can enhance the functionality of the platform by enabling quick, easy, and decentralized financial interactions. Introducing antizaps allows for the reversal or adjustment of previous zaps.

Specification

Zap Transaction Format

When Alice (A) zaps Bob (B) 100000 satoshis for a note N, assuming both A and B have Nostr/Taproot addresses, the transaction would be structured as follows:

Note: that taproot address and npub are interchangable addresses with a different prefix. Sats are transferred to a UTXO the nsec can unlock.

Inputs:

  1. A: 200200 satoshis

Outputs:

  1. OP_RETURN: 80 bytes (640 bits) containing zap (7a6170) + version=1 (31) + type=[pn] (706e) + [NoteID] + [message]
  2. B: 100000 satoshis
  3. A: 100000 satoshis (change - fee)

The OP_RETURN output format is a work-in-progress (WIP) and would need further specification or improvements.

If NoteID is empty you are just zapping the npub nostr user.

Change can be respent back to Alice, or to a change address if preferred.

Negative Zaps (Antizaps)

In addition to regular zaps, the proposal includes negative zaps (antizaps), which can reverse or modify previous zaps. While a zap is an upvote with a payment. An antizap is a downvote with a payment. In an antizap the payment must either be burnt or sent to a neutral party.

Format: version + type + ID + message

Where type values are defined as:

  1. Regular zap
  2. Antizap
  3. Higher characters reserved for future use (e.g. e=event)

OP_RETURN in details

  • First 3 bytes: zap all lower case (use xzap/xxzap for testing so it doesnt not get indexed)
  • 2 bytes: version + type (see below)
  • 32 bytes: noteID -- binary, this could be shortened with a firstbits style index, in future
  • remaining bytes: message "Thanks for the share"

Total bytes: 80

  • magic string zap: 3 bytes : hex 7a6170
  • Version = 1 : 1 byte : hex = 31
  • Type = "p" zap a nostr pubkey : 1 byte : hex = 70
  • Type = "n" zap a nostr note : 1 byte : hex = 6e
  • Type = antizaps : 1 byte : capitalize the type e.g. P,N

Burn addresses

Burn addresses for anti zaps have not yet been specified and should be considered experimental at this point

1BitcoinEaterAddressDontSendf59kuE is an example of one in use, and could be used for test purposes. Though a taproot address would be better.

It is also possible to burn coins by spending them to an OP_RETURN

Implementation Notes

  1. The OP_RETURN field will carry zap information, including a version number, a unique NoteID, and an optional message.
  2. Proper specifications and standards for encoding and decoding zap information in OP_RETURN need to be established.
  3. The mechanism for verifying and processing antizaps must be defined to ensure they accurately reverse or adjust the intended zaps without abuse.

Future Work

  • Develop a comprehensive specification for the OP_RETURN field, including encoding rules and error handling.
  • Establish security measures to prevent misuse of zaps and antizaps.
  • Create tools and libraries to facilitate the integration of zaps and antizaps into Nostr clients.
  • Zaps should be indexed to give fast updates and high score tables.
  • Anonymous zaps can be done using a zapping agent.
  • Allow this to work with subkeys.
  • Use silent payments for added privacy

OP_ZAP

  • It might be an idea to push a magic number onto the script as first byte of the OP_RETURN as a synonym for OP_ZAP
  • suggest OP_15 or OP_16 as the last number pushes, leaning towards 16 right now

Implementations

  • TBD

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment