tyjvazum / arb

◉ Arbitrary Protocols on top of Bitcoin (Bitcoin NFTs/Ordinals, BRC-20, & Bitcoin Identities/Usernames)
GNU General Public License v3.0
22 stars 1 forks source link

Feature: Integrate BRC-20 Protocol #14

Open GaloisField2718 opened 1 year ago

GaloisField2718 commented 1 year ago

Hello,

To continue the chat casey/ord/discussions/2086 about brc-20 integration in ˋord` command.

I didn’t know this repo but I see it can manage multiple protocols from JSON config file so it should be very easy to integrate brc-20 in ˋarb`.

Because the core of the brc-20 principle is only 3 functions based on JSON files.

Related discussion: https://github.com/casey/ord/issues/2078

GaloisField2718 commented 1 year ago

Basically it's only : Deploy

{ "p" : "brc-20", "op" : "deploy", "tick": "xxxx", "amt" : "uint", "lim" : "uint"}

Where "lim" is per mint.

Mint

{ "p" : "brc-20", "op" : "mint", "tick": "xxxx", "amt" : "uint"}

Transfer

{ "p" : "brc-20", "op" : "transfer", "tick": "xxxx", "amt" : "uint"}

I don't the way of functioning for arb on Bitcoin but I will take a look and try the tool.

@tyjvazum, if you want to explain few things and chat about it, it's a pleasure.

tyjvazum commented 1 year ago

Yes, I agree, that sounds reasonable to implement. I'm still building out the structure, named blang, for declaring the validation logic of arbitrary protocols, so supporting BRC-20 seems like a great test case to help with that development and to get something useful out sooner than more complicated protocols like bid. I'll share progress on it as it comes together.

I haven't been paying much attention to fungible tokens in general, so I'm not especially versed on everything in the ecosystem, but I suspect arb could serve as a full node for the protocol.

I'm happy to answer any questions you may have or to discuss the code or features.

stet commented 1 year ago

I came to discuss this too. I'm working also on an Extension Protocol to keep BRC-20 simple and minimal. I was going to experiment with a standalone version as well using arb.

Let's discuss.

tyjvazum commented 1 year ago

I'm working on creating the required generalizations for full BRC-20 support. Perhaps a more minimal interface could be added faster, but I'm not sure what would be useful so I'm open to suggestions. This is my current work-in-progress on the blang syntax that would essentially provide a full node for the protocol:

// DESIGN VERSION 0.3.0
{
    "protocol": "brc-20",
    "version": "1.0.0",
    "ops": {
        "deploy": {
            "template": {
                "p": {
                    "value": "brc-20",
                    "required": true
                },
                "op": {
                    "value": "deploy",
                    "required": true
                },
                "tick": {
                    "type": "STRING",
                    "min_length": 4,
                    "max_length": 4,
                    "valid_chars": "a-z",
                    "required": true,
                    "key": true
                },
                "max": {
                    "type": "NUMBER",
                    "min": 1,
                    "max": "UINT64_MAX",
                    "required": true
                },
                "lim": {
                    "type": "NUMBER",
                    "min": 1,
                    "max": "UINT64_MAX"
                },
                "dec": {
                    "type": "NUMBER",
                    "min": 0,
                    "max": 18
                }
            },
            "script": [
                "$result FROM $state.tick_to_deployment FOR $self.tick MUST_BE_NONE",
                "SET $state.tick_to_deployment FOR $self.tick TO $self"
            ]
        },
        "mint": {
            "template": {
                "p": {
                    "value": "brc-20",
                    "required": true
                },
                "op": {
                    "value": "mint",
                    "required": true
                },
                "tick": {
                    "type": "STRING",
                    "min_length": 4,
                    "max_length": 4,
                    "valid_chars": "a-z",
                    "required": true
                },
                "amt": {
                    "type": "NUMBER",
                    "min": 1,
                    "max": "UINT64_MAX",
                    "required": true
                }
            },
            "script": [
                "$self.tick MUST_MATCH $result.tick FROM $state.tick_to_deployment FOR $self.tick",
                "$self.amt MUST_BE_GT_OR_EQ 1",
                [
                    "$self.amt MUST_BE_LT_OR_EQ $result.lim",
                    "FROM $state.tick_to_deployment FOR $self.tick"
                ],
                [
                    "$result.max FROM $state.tick_to_deployment",
                    "FOR $self.tick MUST_BE_GT $result",
                    "FROM $state.tick_to_total FOR $self.tick"
                ],
                "IF:",
                [
                    "$result.max FROM $state.tick_to_deployment FOR $self.tick MUST_BE_GT",
                    "(($result FROM $state.tick_to_total FOR $self.tick) + $self.amt)"
                ],
                "ELSE:",
                [
                    "SET $self.amt TO ((($result FROM $state.tick_to_total FOR $self.tick) +",
                    "$self.amt) - ($result.max FROM $state.tick_to_deployment FOR $self.tick))"
                ],
                "SET $state.tick_to_total FOR $self.tick TO ($current_value + $self.amt)"
            ]
        },
        "transfer": {
            "template": {
                "p": {
                    "value": "brc-20",
                    "required": true
                },
                "op": {
                    "value": "transfer",
                    "required": true
                },
                "tick": {
                    "type": "STRING",
                    "min_length": 4,
                    "max_length": 4,
                    "valid_chars": "a-z",
                    "required": true
                },
                "amt": {
                    "type": "NUMBER",
                    "min": 1,
                    "max": "UINT64_MAX",
                    "required": true
                }
            },
            "script": [
                "$result.tick FROM $state.tick_to_deployment FOR $self.tick MATCHES $self.tick",
                [
                    "$self.amt MUST_BE_LT_OR_EQ $result",
                    "FROM $state.address_to_balance FOR $owner_address/$self.tick"
                ],
                [
                    "SET $state.address_to_balance",
                    "FOR $owner_address/$self.tick",
                    "TO ($current_value - $self.amt)"
                ],
                [
                    "SET $state.address_to_pending_balance",
                    "FOR $owner_address/$self.tick",
                    "TO ($current_value + $self.amt)"
                ],
                "ONCE_NEXT_OWNER:",
                [
                    "SET $state.address_to_balance",
                    "FOR $owner_address/$self.tick",
                    "TO ($current_value + $self.amt)"
                ]
            ]
        }
    },
    "state": {
        "address_to_balance": "STORE()",
        "address_to_pending_balance": "STORE()",
        "tick_to_deployment": "STORE()",
        "tick_to_total": "STORE()"
    },
    "interface": {
        "balance": {
            "parameters": {
                "tick": {
                    "type": "STRING",
                    "min_length": 4,
                    "max_length": 4,
                    "valid_chars": "a-z",
                    "required": true
                },
                "address": {
                    "type": "STRING"
                }
            },
            "script": [
                "IF: ($args.address MUST_BE_NONE)",
                "$result FROM $state.address_to_balance FOR ...$wallet_addresses/$args.tick",
                "ELSE:",
                "$result FROM $state.address_to_balance FOR $args.address/$args.tick"
            ]
        },
        "deploy": {
            "parameters": [
                "tick",
                "max",
                "lim",
                "dec"
            ],
            "script": [
                "$result FROM $state.tick_to_deployment FOR $args.tick MUST_BE_NONE",
                "INSCRIBE { p='brc-20', op='deploy', $args.tick, $args.max, $args.lim, $args.dec }"
            ]
        },
        "mint": {
            "parameters": [
                "tick",
                "amt"
            ],
            "script": [
                "$args.tick MUST_MATCH $result.tick FROM $state.tick_to_deployment FOR $args.tick",
                "$args.amt MUST_BE_GT_OR_EQ 1",
                [
                    "$args.amt MUST_BE_LT_OR_EQ $result.lim",
                    "FROM $state.tick_to_deployment FOR $args.tick"
                ],
                [
                    "$result.max FROM $state.tick_to_deployment FOR $args.tick",
                    "MUST_BE_GT $result FROM $state.tick_to_total FOR $args.tick"
                ],
                "INSCRIBE { p='brc-20', op='mint', $args.tick, $args.amt }"
            ]
        },
        "transfer": {
            "parameters": [
                "tick",
                "amt"
            ],
            "script": [
                "$result.tick FROM $state.tick_to_deployment FOR $args.tick MATCHES $args.tick",
                [
                    "$args.amt MUST_BE_LT_OR_EQ $result",
                    "FROM $state.address_to_balance FOR $owner_address/$args.tick"
                ],
                "INSCRIBE { p='brc-20', op='transfer', $args.tick, $args.amt }"
            ]
        }
    },
    "expansion": false,
    "tracking": true
}

With expansion set to false and tracking set to true, the protocol would operate as normal ord inscriptions using JSON, as BRC-20 currently does.

This is all experimental, with details like instruction and property names likely to change, but the structure represents what I've been working on with arb overall.


I came to discuss this too. I'm working also on an Extension Protocol to keep BRC-20 simple and minimal. I was going to experiment with a standalone version as well using arb.

Let's discuss.

@stet, I assume you're talking about BRC-21? It looks interesting. We can discuss it with plans to add support after the initial BRC-20 implementation is done.

stet commented 1 year ago

great work so far. i’m in Miami but plan to dive into arb after trip.

yes BRC-21 is a possible path forward. i’ve discussed with domo.

tyjvazum commented 1 year ago

great work so far. i’m in Miami. it plan to dive into arb after trip.

yes BRC-21 is a possible path forward. i’ve discussed with domo.

Awesome. Have a great trip. I've updated the example syntax in my previous message. I've changed some things while getting the Rust implementation that serves as the interpreter ready. As I said, I'm not super familiar with BRC-20 so let me know if anything should be adjusted.

stet commented 1 year ago

This will be a good opp to explore extension protocol and filter out all non-brc inscriptions.

GaloisField2718 commented 1 year ago

Yes, I agree, that sounds reasonable to implement. I'm still building out the structure, named blang, for declaring the validation logic of arbitrary protocols, so supporting BRC-20 seems like a great test case to help with that development and to get something useful out sooner than more complicated protocols like bid. I'll share progress on it as it comes together.

I haven't been paying much attention to fungible tokens in general, so I'm not especially versed on everything in the ecosystem, but I suspect arb could serve as a full node for the protocol.

It's exactly this.

But is it coherent to build other nodes as we already have bitcoin ?

It is acting a bit like a chain on top of bitcoin no ?

And by the way the problem of honesty will come out with arb and full nodes idea no ?

I'm happy to answer any questions you may have or to discuss the code or features.

GaloisField2718 commented 1 year ago

I'm working on creating the required generalizations for full BRC-20 support. Perhaps a more minimal interface could be added faster, but I'm not sure what would be useful so I'm open to suggestions. This is my current work-in-progress on the blang syntax that would essentially provide a full node for the protocol:

I have question : how do you write this json file ? By "yourself" ? Based on another protocol ? ChatGPT (haha we never known 😄) ?

Also are you following this issue on ord https://github.com/casey/ord/issues/2062 it's not directly related but maybe it's interesting to consider this

tyjvazum commented 1 year ago

@stet, if I understand what you mean by filter, yes, only inscriptions matching the BRC-20 pattern would be considered. What do you have in mind regarding the extension protocol?


@GaloisField2718, yes, it acts like a chain on top of Bitcoin, without a separate consensus mechanism. That's what things like BRC-20 inherently are, because they contain additional validation logic that a normal Bitcoin client, or ord, won't validate.

By honesty, if you mean making sure the BRC-20 protocol is correctly followed, yes, that requires an indexer, which can be called a full node. Without that, it's not possible to know things like balances or if a deploy was the first to use a certain tick.

Regarding the JSON file, that's called a protocol spec. It's written by someone, in this case me, but ultimately by anyone that wants to make a protocol using arb.

Yes, I'm following the https://github.com/casey/ord/issues/2062 issue. It'll be quite interesting to see how that bug ends up being fixed or otherwise dealt with.

0attack commented 1 year ago

so these features aren't in the repo yet but they will almost be like a language for writing smart contracts? is this related to https://github.com/tyjvazum/arb/issues/5?

tyjvazum commented 1 year ago

so these features aren't in the repo yet but they will almost be like a language for writing smart contracts? is this related to #5?

@0attack, correct, only basic support for protocol specs is in the current code.

It's in a similar category to smart contracts, but I wouldn't call it that in general. It's a language for writing protocols using inscriptions, which could have features similar to smart contracts, but it's all still early in development.

Yes, issue https://github.com/tyjvazum/arb/issues/5 represents the general functionality whereas this issue is specifically about BRC-20.


I've updated the example syntax in my previous message. Implementation is going well.

As an overview, the major parts are ops (which declare the types of inscriptions the protocol recognizes), stores (which declare the key-value databases for the protocol), interfaces (which declare the command-line options for the protocol), and scripts (which declare the logic to use an interface or validate an inscription).

A given script is an array containing one or more conditions that are either a single string or an array of strings (just for readability purposes). When an array of strings, the array elements are joined into a single string with a single space character between each element. Each condition is evaluated to true or false and the script fails once a condition evaluates to false, with the exception of IF/ELSE blocks, which only cause the script to fail if the entire block evaluates to false.

I'll continue posting progress as I work, and as always, feedback or questions are encouraged 🙂