Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bitlightlabs/bitlight-rgb20-contract
RGB20 Contract Demo based on RGB v0.11.0-beta.5
https://github.com/bitlightlabs/bitlight-rgb20-contract
contract rgb20
Last synced: 2 months ago
JSON representation
RGB20 Contract Demo based on RGB v0.11.0-beta.5
- Host: GitHub
- URL: https://github.com/bitlightlabs/bitlight-rgb20-contract
- Owner: bitlightlabs
- License: apache-2.0
- Created: 2024-03-16T14:59:16.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2024-04-14T18:47:00.000Z (9 months ago)
- Last Synced: 2024-04-24T05:07:37.283Z (9 months ago)
- Topics: contract, rgb20
- Language: Rust
- Homepage: https://bitlightlabs.com
- Size: 101 KB
- Stars: 12
- Watchers: 2
- Forks: 6
- Open Issues: 0
-
Metadata Files:
- Readme: Readme.md
- License: LICENSE
Awesome Lists containing this project
- awesome-rgb-protocol - RGB20 Demo based on RGB v0.11 by Bitlight Labs
README
# RGB20 Demo based on RGB v0.11
## Pre-request
To complete the demo, you need to set up the following toolchains:
1. [Git][git]
2. [Rust][rust]
3. [RGB-CLI][rgb-cli]
4. [Bitcoin Local Env][bitlight-local-env-public][git]: https://git-scm.com/
[rust]: https://www.rust-lang.org/tools/install
[rgb-cli]: https://github.com/RGB-WG/rgb
[bitlight-local-env-public]: https://github.com/bitlightlabs/bitlight-local-env-public/
### RGB-CLI
First, clone it from GitHub:
```bash
git clone https://github.com/RGB-WG/rgb.git
```Then, build it, copy the binary to `~/.cargo/bin/`:
```
cd rgb
cargo build --package rgb-wallet --bin rgb --release
cp target/release/rgb ~/.cargo/bin/
```### Bitcoin Local Env
Run `make up` to start the development environment
```bash
git clone https://github.com/bitlightlabs/bitlight-local-env-public/
make up
```Write down Alice's xprv and Bitcoin address.
```
make alice-cli
``````text
Network : regtest
Wallet Name : alice
Root XPRV : tprv8ZgxMBicQKsPeHzjP5LTL818LxwHbJNLZRa98Qdnn7M98fW15365cB1Sz9QZvYufASRKH6JEPhfpxVuFTKMHxDcEAVboqKuZdMmxzKVhMnW
Fixed XPUB : [5183a8d8/86'/1'/0']tpubDDtdVYn7LWnWNUXADgoLGu48aLH4dZ17hYfRfV9rjB7QQK3BrphnrSV6pGAeyfyiAM7DmXPJgRzGoBdwWvRoFdJoMVpWfmM9FCk8ojVhbMS/<0;1;9;10>/*
Bitcoin Address : bcrt1pn0s2pajhsw38fnpgcj79w3kr3c0r89y3xyekjt8qaudje70g4shs20nwfx
```Write down Bob's xprv and Bitcoin address.
```
make bob-cli
``````text
Network : regtest
Wallet Name : bob
Root XPRV : tprv8ZgxMBicQKsPeEP6QyHbs7W2pfW5FJisXLcX93h2AnH5Kx8fuhKz7FYm4kw46SUgXJd3zUKwNoTqxtpLw7vmtLeFUGJb6XSeom45hQjeXxJ
Fixed XPUB : [3abb3cbb/86'/1'/0']tpubDDeBXqUqyVcbe75SbHAPNXMojntFu5C8KTUEhnyQc74Bty6h8XxqmCavPBMd1fqQQAAYDdp6MAAcN4e2eJQFH3v4txc89s8wvHg98QSUrdL/<0;1;9;10>/*
Bitcoin Address : bcrt1plphl407vyfpml2thhypzuqk232256njnaw4zhtmyrrku66pqn9usx4x59h
```get satoshis faucet for alice and bob
```
make core-cli
load_wallet
# alice
send bcrt1pn0s2pajhsw38fnpgcj79w3kr3c0r89y3xyekjt8qaudje70g4shs20nwfx 1
send bcrt1plphl407vyfpml2thhypzuqk232256njnaw4zhtmyrrku66pqn9usx4x59h 1
send bcrt1pr3rupmav8a7av7dqfyvynu2wk02lduggnh9ln4ndze9aqvuv9y3sklwrss 1
# bob
send bcrt1p9yjaffzhuh9p7d9gnwfunxssngesk25tz7rudu4v69dl6e7w7qhq5x43k5 1
mint 1
```## Create and Import Contract
To create a RGB20 contract, just clone this repo to you local machine. Then
compile and run it.```bash
$ git clone https://github.com/bitlightlabs/bitlight-rgb20-contract
$ cd bitlight-rgb20-contract
```edit main.rs, change the beneficiary to alice's address
```rust
let beneficiary_txid =
Txid::from_hex("d6afd1233f2c3a7228ae2f07d64b2091db0d66f2e8ef169cf01217617f51b8fb").unwrap();
let beneficiary = Outpoint::new(beneficiary_txid, 1);
```Export ESPLORA_SERVER env for esplora-api endpoint:
```bash
$ export LNPBP_NETWORK=regtest
$ export ESPLORA_SERVER="http://esplora-api.bitlight-local-env.orb.local:3000"
```_note: a locally running bitlight-local-env-esplora-**api** docker container instance should export **ESPLORA_SERVER**
value:_```bash
$ export ESPLORA_SERVER="http://localhost:3002"
```_and locally running bitlight-local-env-esplora (server / non-api) docker container client constructor parameter
in [examples/broadcast-tx.rs](examples/broadcast-tx.rs) set to:_```rust
esplora_client::Builder::new("http://localhost:5002")
``````bash
$ make runThe issued contract data:
{"ticker":"TEST","name":"Test asset","details":null,"precision":"centiMicro"}
amount=adMhBHaQ, owner=bc:tapret1st:311ec7d43f0f33cda5a0c515a737b5e0bbce3896e6eb32e67db0e868a58f4150:1, witness=~
totalSupply=adMhBHaQContracts are available in the test directory
---------------------------------
./test:
-rw-r--r-- 1 bitlight staff 21364 Mar 15 19:57 rgb20-simplest.rgb
-rw-r--r-- 1 bitlight staff 27456 Mar 15 19:57 rgb20-simplest.rgba
---------------------------------
```Now, we are creating a RGB20 #TEST contract, which stores in `test` folder.
Before importing contracts, let's import our wallets to rgb.
Export ESPLORA_SERVER env for esplora-api endpoint:
```bash
export LNPBP_NETWORK=regtest
export ESPLORA_SERVER="http://esplora-api.bitlight-local-env.orb.local:3000"
```Create rgb wallet container for Alice:
```bash
$ rgb -d .alice create default --tapret-key-only
$ rgb -d .alice create default --tapret-key-only "[5183a8d8/86'/1'/0']tpubDDtdVYn7LWnWNUXADgoLGu48aLH4dZ17hYfRfV9rjB7QQK3BrphnrSV6pGAeyfyiAM7DmXPJgRzGoBdwWvRoFdJoMVpWfmM9FCk8ojVhbMS/<0;1;9;10>/*"Loading descriptor from command-line argument ... success
Syncing keychain 0 ........... keychain 1 .......... keychain 9 .......... keychain 10 .......... success
Saving the wallet as 'default' ... success$ rgb -d .alice utxos
Height Amount, ṩ Outpoint
bcrt1pn0s2pajhsw38fnpgcj79w3kr3c0r89y3xyekjt8qaudje70g4shs20nwfx &0/0
102 100000000 d6afd1233f2c3a7228ae2f07d64b2091db0d66f2e8ef169cf01217617f51b8fb:1Loading descriptor from wallet default ... success
Wallet total balance: 100000000 ṩ
```
Create rgb wallet container for Bob:
```bash
$ rgb -d .bob create default --tapret-key-onlyLoading descriptor from command-line argument ... success
Syncing keychain 0 ........... keychain 1 .......... keychain 9 .......... keychain 10 .......... success
Saving the wallet as 'default' ... success$ rgb -d .bob utxos
Height Amount, ṩ Outpoint
bcrt1plphl407vyfpml2thhypzuqk232256njnaw4zhtmyrrku66pqn9usx4x59h &0/0
102 100000000 389bf4b8c31d5dca7e36cffc361a8a020916cb242015e816ccacfa5312be564c:0Loading descriptor from wallet default ... success
Wallet total balance: 100000000 ṩ
```
Import contract for Alice
```
$ rgb -d .alice import test/rgb20-simplest.rgbImporting consignment rgb:csg:D6$4UcFP-6siMEPG-z5WedGG-!gfynub-7vIFN93-KGneAc4#parking-agent-parody:
- validating the contract rgb:2TglHDbZ-!ntHfLf-yLEEFpM-o!sLGAz-Bw84b8m-hXRuSW0 ... success
Consignment is imported
```After that, we can inspect contracts state with `rgb state` command.
get the state of the contract for Alice
```bash
$ rgb -d .alice contracts
rgb:2TglHDbZ-!ntHfLf-yLEEFpM-o!sLGAz-Bw84b8m-hXRuSW0 bitcoin 2024-06-13 rgb:sch:KzMZV9bO7gFhox97!klj0FonG2ZKnjuOIg2tFChu$YA#lucas-episode-silicon
Developer: ssi:anonymous
$ export RGB20_CONTRACT="rgb:2TglHDbZ-!ntHfLf-yLEEFpM-o!sLGAz-Bw84b8m-hXRuSW0"
```_note: special characters (such as "**$**") in RGB20_CONTRACT environment variable will need escaping, i.e.,_
```bash
$ export RGB20_CONTRACT="rgb:vi09buwx-VuXsvVi-VBA9Htw-sL5Vf81-22oM0V1-pxpGi\$c"
↑
``````bash
# rgb -d state
$ rgb -d .alice state $RGB20_CONTRACT RGB20FixedGlobal:
spec := (ticker=("TEST"), name=("Test asset"), details=~, precision=8)
terms := (text=(""), media=~)
issuedSupply := (100000000000)Owned:
assetOwner:
value=adMhBHaQ, utxo=bc:tapret1st:311ec7d43f0f33cda5a0c515a737b5e0bbce3896e6eb32e67db0e868a58f4150:1, witness=~
```Print operation history for Alice
```
$ rgb -d .alice history $RGB20_CONTRACTLoading descriptor from wallet default ... success
Operation Value Seal Witness
issued adMhBHaQ bc:tapret1st:311ec7d43f0f33cda5a0c515a737b5e0bbce3896e6eb32e67db0e868a58f4150:1 ~
```Import contract For Bob:
```bash
$ rgb -d .bob import test/rgb20-simplest.rgb
$ rgb -d .bob contracts
$ rgb -d .bob state $RGB20_CONTRACT RGB20FixedGlobal:
spec := (ticker=("TEST"), name=("Test asset"), details=~, precision=8)
terms := (text=(""), media=~)
issuedSupply := (100000000000)Owned:
assetOwner:
```Now we have successfully created an rgb20 token, and the owner
is `bc:tapret1st:311ec7d43f0f33cda5a0c515a737b5e0bbce3896e6eb32e67db0e868a58f4150:1`, which belongs to Alice.## Transfer
There are about five steps in a complete transfer:
1. Create an invoice
2. Construct a PSBT
3. Make a transfer
4. Accept the transfer
5. Sign the PSBT and broadcast it### Create an invoice
To receive 1,000 #Test, Bob needs to create an invoice and send it to Alice.
```bash
$ rgb -d .bob invoice $RGB20_CONTRACT RGB20Fixed 2000
rgb:2TglHDbZ-!ntHfLf-yLEEFpM-o!sLGAz-Bw84b8m-hXRuSW0/RGB20Fixed/TadF+bcrt:utxob:4HhkKFP6-92o3r0C-EUCK1DI-k0hamBB-CU9xauX-GhjVSHs-IRESQ
```### Make a transfer
```bash
$ rgb -d .alice transfer \
rgb:2TglHDbZ-!ntHfLf-yLEEFpM-o!sLGAz-Bw84b8m-hXRuSW0/RGB20Fixed/TadF+bcrt:utxob:4HhkKFP6-92o3r0C-EUCK1DI-k0hamBB-CU9xauX-GhjVSHs-IRESQ \
transfer.consignment alice.psbt
```The consignment is saved in the `transfer.consignment` file, and needs to be sent to Bob, who is waiting to accept it.
### Accept transfer
After receiving the `transfer.consignment` file, Bob could validate it before accepting.
```bash
$ rgb -d .bob validate transfer.consignment
The provided consignment is valid
```Bob accepts the consignment:
```bash
$ rgb -d .bob accept -f transfer.consignment
Transfer accepted into the stash
```### Sign psbt and broadcast it
#### Sign psbt
Let's inspect the psbt file:
```bash
$ hal psbt decode --regtest alice.psbt
``````json
{
"unsigned_tx": {
"txid": "0fd2b9f690428f751aa381c82cadf52b50ced63616802fe0803cb983d5ac3e1a",
"wtxid": "0fd2b9f690428f751aa381c82cadf52b50ced63616802fe0803cb983d5ac3e1a",
"size": 137,
"weight": 548,
"vsize": 137,
"version": 2,
"locktime": 0,
"inputs": [
{
"prevout": "d6afd1233f2c3a7228ae2f07d64b2091db0d66f2e8ef169cf01217617f51b8fb:1",
"txid": "d6afd1233f2c3a7228ae2f07d64b2091db0d66f2e8ef169cf01217617f51b8fb",
"vout": 1,
"script_sig": {
"hex": "",
"asm": ""
},
"sequence": 0,
"witness": null
}
],
"outputs": [
{
"value": 99997600,
"script_pub_key": {
"hex": "51209aa1750ffc777b77b7a5e92202e75980072afbec58d51c5130d5857445c8ab20",
"asm": "OP_PUSHNUM_1 OP_PUSHBYTES_32 9aa1750ffc777b77b7a5e92202e75980072afbec58d51c5130d5857445c8ab20",
"type": "unknown",
"address": "bcrt1pn2sh2rluwaah0da9ay3q9e6esqrj47lvtr23c5fs6kzhg3wg4vsqldfds2"
}
},
{
"value": 2000,
"script_pub_key": {
"hex": "51202925d4a457e5ca1f34a89b93c99a109a330b2a8b1787c6f2acd15bfd67cef02e",
"asm": "OP_PUSHNUM_1 OP_PUSHBYTES_32 2925d4a457e5ca1f34a89b93c99a109a330b2a8b1787c6f2acd15bfd67cef02e",
"type": "unknown",
"address": "bcrt1p9yjaffzhuh9p7d9gnwfunxssngesk25tz7rudu4v69dl6e7w7qhq5x43k5"
}
}
],
"total_output_value": 99999600
},
"inputs": [
{
"witness_utxo": {
"value": 100000000,
"script_pub_key": {
"hex": "51209be0a0f65783a274cc28c4bc5746c38e1e3394913133692ce0ef1b2cf9e8ac2f",
"asm": "OP_PUSHNUM_1 OP_PUSHBYTES_32 9be0a0f65783a274cc28c4bc5746c38e1e3394913133692ce0ef1b2cf9e8ac2f",
"type": "unknown",
"address": "bcrt1pn0s2pajhsw38fnpgcj79w3kr3c0r89y3xyekjt8qaudje70g4shs20nwfx"
}
}
}
],
"outputs": [
{},
{}
]
}
```Now, it's Alice's turn to sign the PSBT file and broadcast it.
Sign the PSBT with sparrow, hal, or bdk-cli.
```shell
$ bdk-cli -n regtest wallet --descriptor "tr(tprv8ZgxMBicQKsPeHzjP5LTL818LxwHbJNLZRa98Qdnn7M98fW15365cB1Sz9QZvYufASRKH6JEPhfpxVuFTKMHxDcEAVboqKuZdMmxzKVhMnW/86'/1'/0'/0/*)" \
sign --psbt $(cat alice.psbt | base64 | tr -d '\r\n') | jq -r '.psbt' | base64 --decode > alice.psbt.signed$ hal psbt finalize alice.psbt.signed
0200000000010184cc73022f7b19317eb3490f10ef7f0...27921857420c21461a205c5b60ca54c00000000
```Set the signed PSBT hex encoding string to SOME_TX in examples/broadcast-tx.rs
After broadcasting, mine 1 block.
```
cargo run --example broadcast-tx
``````
cd
make core-cli
mint 1
```At that time, Bob and Alice would get different outputs with `rgb state` and `rgb validate`.
### Check Alice and Bob's RGB state
For Alice:
```bash
$ rgb -d .alice state $RGB20_CONTRACT RGB20Fixed --syncGlobal:
spec := (ticker=("TEST"), name=("Test asset"), details=~, precision=8)
terms := (text=(""), media=~)
issuedSupply := (100000000000)Owned:
assetOwner:
value=99999998000, utxo=bc:tapret1st:ff66b39da83f310fb75db3336c9cf509dfd68ecfb7ea67fa556b5160eafe3a9f:0, witness=bc:ff66b39da83f310fb75db3336c9cf509dfd68ecfb7ea67fa556b5160eafe3a9f
``````bash
$ rgb -d .alice history $RGB20_CONTRACT```
For Bob:
```bash
$ rgb -d .bob state $RGB20_CONTRACT RGB20Fixed --syncGlobal:
spec := (ticker=("TEST"), name=("Test asset"), details=~, precision=8)
terms := (text=(""), media=~)
issuedSupply := (100000000000)Owned:
assetOwner:
value=2000, utxo=bc:tapret1st:04099eb216c8ac6c1767de0c7b6076b2dcabf63583ece8e6f9ccfd6c4cd4a95f:0, witness=bc:ff66b39da83f310fb75db3336c9cf509dfd68ecfb7ea67fa556b5160eafe3a9f
``````bash
$ rgb -d .bob history $RGB20_CONTRACTLoading descriptor from wallet default ... success
Operation Value Seal Witness
received TadF bc:tapret1st:04099eb216c8ac6c1767de0c7b6076b2dcabf63583ece8e6f9ccfd6c4cd4a95f:0 bc:8d6f2936ef1bb39728821e1af97b950b6941de64450e6fabaec20c8cb0f970a9 (105@1726911117)```